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

Commit 59a0baff authored by Seigo Nonaka's avatar Seigo Nonaka
Browse files

Add new API useful for determining text height for empty text field

Bug: 303326708
Test: atest Paint_FontMetricsForLocaleTest
Change-Id: I4395c778a8de459ffdddba0c0d4dc2ba050e50ac
parent 73a14015
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -16086,10 +16086,12 @@ package android.graphics {
    method public String getFontFeatureSettings();
    method public float getFontMetrics(android.graphics.Paint.FontMetrics);
    method public android.graphics.Paint.FontMetrics getFontMetrics();
    method @FlaggedApi("com.android.text.flags.fix_line_height_for_locale") public void getFontMetricsForLocale(@NonNull android.graphics.Paint.FontMetrics);
    method public void getFontMetricsInt(@NonNull CharSequence, @IntRange(from=0) int, @IntRange(from=0) int, @IntRange(from=0) int, @IntRange(from=0) int, boolean, @NonNull android.graphics.Paint.FontMetricsInt);
    method public void getFontMetricsInt(@NonNull char[], @IntRange(from=0) int, @IntRange(from=0) int, @IntRange(from=0) int, @IntRange(from=0) int, boolean, @NonNull android.graphics.Paint.FontMetricsInt);
    method public int getFontMetricsInt(android.graphics.Paint.FontMetricsInt);
    method public android.graphics.Paint.FontMetricsInt getFontMetricsInt();
    method @FlaggedApi("com.android.text.flags.fix_line_height_for_locale") public void getFontMetricsIntForLocale(@NonNull android.graphics.Paint.FontMetricsInt);
    method public float getFontSpacing();
    method public String getFontVariationSettings();
    method public int getHinting();
+8 −0
Original line number Diff line number Diff line
package: "com.android.text.flags"

flag {
  name: "fix_line_height_for_locale"
  namespace: "text"
  description: "Feature flag that preserve the line height of the TextView and EditText even if the the locale is different from Latin"
  bug: "303326708"
}
+61 −4
Original line number Diff line number Diff line
@@ -16,8 +16,11 @@

package android.graphics;

import static com.android.text.flags.Flags.FLAG_FIX_LINE_HEIGHT_FOR_LOCALE;

import android.annotation.ColorInt;
import android.annotation.ColorLong;
import android.annotation.FlaggedApi;
import android.annotation.IntDef;
import android.annotation.IntRange;
import android.annotation.NonNull;
@@ -2125,7 +2128,7 @@ public class Paint {
     * @return the font's recommended interline spacing.
     */
    public float getFontMetrics(FontMetrics metrics) {
        return nGetFontMetrics(mNativePaint, metrics);
        return nGetFontMetrics(mNativePaint, metrics, false);
    }

    /**
@@ -2138,6 +2141,32 @@ public class Paint {
        return fm;
    }

    /**
     * Get the font metrics used for the locale
     *
     * Obtain the metrics of the font that is used for the specified locale by
     * {@link #setTextLocales(LocaleList)}. If multiple locales are specified, the minimum ascent
     * and maximum descent will be set.
     *
     * This API is useful for determining the default line height of the empty text field, e.g.
     * {@link android.widget.EditText}.
     *
     * Note, if the {@link android.graphics.Typeface} is created from the custom font files, its
     * metrics are reserved, i.e. the ascent will be the custom font's ascent or smaller, the
     * descent will be the custom font's descent or larger.
     *
     * Note, if the {@link android.graphics.Typeface} is a system fallback, e.g.
     * {@link android.graphics.Typeface#SERIF}, the default font's metrics are reserved, i.e. the
     * ascent will be the serif font's ascent or smaller, the descent will be the serif font's
     * descent or larger.
     *
     * @param metrics an output parameter. All members will be set by calling this function.
     */
    @FlaggedApi(FLAG_FIX_LINE_HEIGHT_FOR_LOCALE)
    public void getFontMetricsForLocale(@NonNull FontMetrics metrics) {
        nGetFontMetrics(mNativePaint, metrics, true);
    }

    /**
     * Returns the font metrics value for the given text.
     *
@@ -2318,7 +2347,7 @@ public class Paint {
     * @return the font's interline spacing.
     */
    public int getFontMetricsInt(FontMetricsInt fmi) {
        return nGetFontMetricsInt(mNativePaint, fmi);
        return nGetFontMetricsInt(mNativePaint, fmi, false);
    }

    public FontMetricsInt getFontMetricsInt() {
@@ -2327,6 +2356,32 @@ public class Paint {
        return fm;
    }

    /**
     * Get the font metrics used for the locale
     *
     * Obtain the metrics of the font that is used for the specified locale by
     * {@link #setTextLocales(LocaleList)}. If multiple locales are specified, the minimum ascent
     * and maximum descent will be set.
     *
     * This API is useful for determining the default line height of the empty text field, e.g.
     * {@link android.widget.EditText}.
     *
     * Note, if the {@link android.graphics.Typeface} is created from the custom font files, its
     * metrics are reserved, i.e. the ascent will be the custom font's ascent or smaller, the
     * descent will be the custom font's descent or larger.
     *
     * Note, if the {@link android.graphics.Typeface} is a system fallback, e.g.
     * {@link android.graphics.Typeface#SERIF}, the default font's metrics are reserved, i.e. the
     * ascent will be the serif font's ascent or smaller, the descent will be the serif font's
     * descent or larger.
     *
     * @param metrics an output parameter. All members will be set by calling this function.
     */
    @FlaggedApi(FLAG_FIX_LINE_HEIGHT_FOR_LOCALE)
    public void getFontMetricsIntForLocale(@NonNull FontMetricsInt metrics) {
        nGetFontMetricsInt(mNativePaint, metrics, true);
    }

    /**
     * Return the recommend line spacing based on the current typeface and
     * text size.
@@ -3446,9 +3501,11 @@ public class Paint {
    @FastNative
    private static native void nSetFontFeatureSettings(long paintPtr, String settings);
    @FastNative
    private static native float nGetFontMetrics(long paintPtr, FontMetrics metrics);
    private static native float nGetFontMetrics(long paintPtr, FontMetrics metrics,
            boolean useLocale);
    @FastNative
    private static native int nGetFontMetricsInt(long paintPtr, FontMetricsInt fmi);
    private static native int nGetFontMetricsInt(long paintPtr, FontMetricsInt fmi,
            boolean useLocale);

    // ---------------- @CriticalNative ------------------------

+25 −13
Original line number Diff line number Diff line
@@ -593,7 +593,7 @@ namespace PaintGlue {
        return result;
    }

    static SkScalar getMetricsInternal(jlong paintHandle, SkFontMetrics *metrics) {
    static SkScalar getMetricsInternal(jlong paintHandle, SkFontMetrics* metrics, bool useLocale) {
        const int kElegantTop = 2500;
        const int kElegantBottom = -1000;
        const int kElegantAscent = 1900;
@@ -622,6 +622,17 @@ namespace PaintGlue {
            metrics->fLeading = size * kElegantLeading / 2048;
            spacing = metrics->fDescent - metrics->fAscent + metrics->fLeading;
        }

        if (useLocale) {
            minikin::MinikinPaint minikinPaint = MinikinUtils::prepareMinikinPaint(paint, typeface);
            minikin::MinikinExtent extent =
                    typeface->fFontCollection->getReferenceExtentForLocale(minikinPaint);
            metrics->fAscent = std::min(extent.ascent, metrics->fAscent);
            metrics->fDescent = std::max(extent.descent, metrics->fDescent);
            metrics->fTop = std::min(metrics->fAscent, metrics->fTop);
            metrics->fBottom = std::max(metrics->fDescent, metrics->fBottom);
        }

        return spacing;
    }

@@ -634,7 +645,7 @@ namespace PaintGlue {
                MinikinUtils::getFontExtent(paint, bidiFlags, typeface, buf, start, count, bufSize);

        SkFontMetrics metrics;
        getMetricsInternal(paintHandle, &metrics);
        getMetricsInternal(paintHandle, &metrics, false /* useLocale */);

        metrics.fAscent = extent.ascent;
        metrics.fDescent = extent.descent;
@@ -686,20 +697,21 @@ namespace PaintGlue {
        }
    }

    static jfloat getFontMetrics(JNIEnv* env, jobject, jlong paintHandle, jobject metricsObj) {
    static jfloat getFontMetrics(JNIEnv* env, jobject, jlong paintHandle, jobject metricsObj,
                                 jboolean useLocale) {
        SkFontMetrics metrics;
        SkScalar spacing = getMetricsInternal(paintHandle, &metrics);
        SkScalar spacing = getMetricsInternal(paintHandle, &metrics, useLocale);
        GraphicsJNI::set_metrics(env, metricsObj, metrics);
        return SkScalarToFloat(spacing);
    }

    static jint getFontMetricsInt(JNIEnv* env, jobject, jlong paintHandle, jobject metricsObj) {
    static jint getFontMetricsInt(JNIEnv* env, jobject, jlong paintHandle, jobject metricsObj,
                                  jboolean useLocale) {
        SkFontMetrics metrics;
        getMetricsInternal(paintHandle, &metrics);
        getMetricsInternal(paintHandle, &metrics, useLocale);
        return GraphicsJNI::set_metrics_int(env, metricsObj, metrics);
    }


    // ------------------ @CriticalNative ---------------------------

    static void reset(CRITICAL_JNI_PARAMS_COMMA jlong objHandle) {
@@ -1002,19 +1014,19 @@ namespace PaintGlue {

    static jfloat ascent(CRITICAL_JNI_PARAMS_COMMA jlong paintHandle) {
        SkFontMetrics metrics;
        getMetricsInternal(paintHandle, &metrics);
        getMetricsInternal(paintHandle, &metrics, false /* useLocale */);
        return SkScalarToFloat(metrics.fAscent);
    }

    static jfloat descent(CRITICAL_JNI_PARAMS_COMMA jlong paintHandle) {
        SkFontMetrics metrics;
        getMetricsInternal(paintHandle, &metrics);
        getMetricsInternal(paintHandle, &metrics, false /* useLocale */);
        return SkScalarToFloat(metrics.fDescent);
    }

    static jfloat getUnderlinePosition(CRITICAL_JNI_PARAMS_COMMA jlong paintHandle) {
        SkFontMetrics metrics;
        getMetricsInternal(paintHandle, &metrics);
        getMetricsInternal(paintHandle, &metrics, false /* useLocale */);
        SkScalar position;
        if (metrics.hasUnderlinePosition(&position)) {
            return SkScalarToFloat(position);
@@ -1026,7 +1038,7 @@ namespace PaintGlue {

    static jfloat getUnderlineThickness(CRITICAL_JNI_PARAMS_COMMA jlong paintHandle) {
        SkFontMetrics metrics;
        getMetricsInternal(paintHandle, &metrics);
        getMetricsInternal(paintHandle, &metrics, false /* useLocale */);
        SkScalar thickness;
        if (metrics.hasUnderlineThickness(&thickness)) {
            return SkScalarToFloat(thickness);
@@ -1121,9 +1133,9 @@ static const JNINativeMethod methods[] = {
        {"nSetTextLocales", "(JLjava/lang/String;)I", (void*)PaintGlue::setTextLocales},
        {"nSetFontFeatureSettings", "(JLjava/lang/String;)V",
         (void*)PaintGlue::setFontFeatureSettings},
        {"nGetFontMetrics", "(JLandroid/graphics/Paint$FontMetrics;)F",
        {"nGetFontMetrics", "(JLandroid/graphics/Paint$FontMetrics;Z)F",
         (void*)PaintGlue::getFontMetrics},
        {"nGetFontMetricsInt", "(JLandroid/graphics/Paint$FontMetricsInt;)I",
        {"nGetFontMetricsInt", "(JLandroid/graphics/Paint$FontMetricsInt;Z)I",
         (void*)PaintGlue::getFontMetricsInt},

        // --------------- @CriticalNative ------------------