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

Commit 008d6d03 authored by Roozbeh Pournader's avatar Roozbeh Pournader Committed by Android (Google) Code Review
Browse files

Merge "Add LocaleList support to Paint and TextView."

parents 6b49d300 a23748a9
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
@@ -11588,6 +11588,7 @@ package android.graphics {
    method public void getTextBounds(java.lang.String, int, int, android.graphics.Rect);
    method public void getTextBounds(char[], int, int, android.graphics.Rect);
    method public java.util.Locale getTextLocale();
    method public android.util.LocaleList getTextLocales();
    method public void getTextPath(char[], int, int, float, float, android.graphics.Path);
    method public void getTextPath(java.lang.String, int, int, float, float, android.graphics.Path);
    method public float getTextScaleX();
@@ -11643,6 +11644,7 @@ package android.graphics {
    method public void setSubpixelText(boolean);
    method public void setTextAlign(android.graphics.Paint.Align);
    method public void setTextLocale(java.util.Locale);
    method public void setTextLocales(android.util.LocaleList);
    method public void setTextScaleX(float);
    method public void setTextSize(float);
    method public void setTextSkewX(float);
@@ -34207,6 +34209,7 @@ package android.util {
    ctor public LocaleList(java.util.Locale[]);
    method public static android.util.LocaleList forLanguageTags(java.lang.String);
    method public java.util.Locale get(int);
    method public static android.util.LocaleList getDefault();
    method public static android.util.LocaleList getEmptyLocaleList();
    method public java.util.Locale getPrimary();
    method public boolean isEmpty();
@@ -41719,6 +41722,7 @@ package android.widget {
    method public java.lang.CharSequence getText();
    method public final android.content.res.ColorStateList getTextColors();
    method public java.util.Locale getTextLocale();
    method public android.util.LocaleList getTextLocales();
    method public float getTextScaleX();
    method public float getTextSize();
    method public int getTotalPaddingBottom();
@@ -41831,6 +41835,7 @@ package android.widget {
    method public final void setTextKeepState(java.lang.CharSequence);
    method public final void setTextKeepState(java.lang.CharSequence, android.widget.TextView.BufferType);
    method public void setTextLocale(java.util.Locale);
    method public void setTextLocales(android.util.LocaleList);
    method public void setTextScaleX(float);
    method public void setTextSize(float);
    method public void setTextSize(int, float);
+5 −0
Original line number Diff line number Diff line
@@ -11925,6 +11925,7 @@ package android.graphics {
    method public void getTextBounds(java.lang.String, int, int, android.graphics.Rect);
    method public void getTextBounds(char[], int, int, android.graphics.Rect);
    method public java.util.Locale getTextLocale();
    method public android.util.LocaleList getTextLocales();
    method public void getTextPath(char[], int, int, float, float, android.graphics.Path);
    method public void getTextPath(java.lang.String, int, int, float, float, android.graphics.Path);
    method public float getTextScaleX();
@@ -11980,6 +11981,7 @@ package android.graphics {
    method public void setSubpixelText(boolean);
    method public void setTextAlign(android.graphics.Paint.Align);
    method public void setTextLocale(java.util.Locale);
    method public void setTextLocales(android.util.LocaleList);
    method public void setTextScaleX(float);
    method public void setTextSize(float);
    method public void setTextSkewX(float);
@@ -36501,6 +36503,7 @@ package android.util {
    ctor public LocaleList(java.util.Locale[]);
    method public static android.util.LocaleList forLanguageTags(java.lang.String);
    method public java.util.Locale get(int);
    method public static android.util.LocaleList getDefault();
    method public static android.util.LocaleList getEmptyLocaleList();
    method public java.util.Locale getPrimary();
    method public boolean isEmpty();
@@ -44327,6 +44330,7 @@ package android.widget {
    method public java.lang.CharSequence getText();
    method public final android.content.res.ColorStateList getTextColors();
    method public java.util.Locale getTextLocale();
    method public android.util.LocaleList getTextLocales();
    method public float getTextScaleX();
    method public float getTextSize();
    method public int getTotalPaddingBottom();
@@ -44439,6 +44443,7 @@ package android.widget {
    method public final void setTextKeepState(java.lang.CharSequence);
    method public final void setTextKeepState(java.lang.CharSequence, android.widget.TextView.BufferType);
    method public void setTextLocale(java.util.Locale);
    method public void setTextLocales(android.util.LocaleList);
    method public void setTextScaleX(float);
    method public void setTextSize(float);
    method public void setTextSize(int, float);
+22 −0
Original line number Diff line number Diff line
@@ -16,7 +16,11 @@

package android.util;

import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.Size;

import com.android.internal.annotations.GuardedBy;

import java.util.HashSet;
import java.util.Locale;
@@ -164,4 +168,22 @@ public final class LocaleList {
            return new LocaleList(localeArray);
        }
    }

    private final static Object sLock = new Object();

    @GuardedBy("sLock")
    private static LocaleList sDefaultLocaleList;

    // TODO: fix this to return the default system locale list once we have that
    @NonNull @Size(min=1)
    public static LocaleList getDefault() {
        Locale defaultLocale = Locale.getDefault();
        synchronized (sLock) {
            if (sDefaultLocaleList == null || sDefaultLocaleList.size() != 1
                    || !defaultLocale.equals(sDefaultLocaleList.getPrimary())) {
                sDefaultLocaleList = new LocaleList(defaultLocale);
            }
        }
        return sDefaultLocaleList;
    }
}
+39 −11
Original line number Diff line number Diff line
@@ -21,6 +21,7 @@ import android.annotation.ColorInt;
import android.annotation.DrawableRes;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.Size;
import android.annotation.StringRes;
import android.annotation.StyleRes;
import android.annotation.XmlRes;
@@ -103,6 +104,7 @@ import android.text.style.URLSpan;
import android.text.style.UpdateAppearance;
import android.text.util.Linkify;
import android.util.AttributeSet;
import android.util.LocaleList;
import android.util.Log;
import android.util.TypedValue;
import android.view.AccessibilityIterators.TextSegmentIterator;
@@ -553,7 +555,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
    private final TextPaint mTextPaint;
    private boolean mUserSetTextScaleX;
    private Layout mLayout;
    private boolean mLocaleChanged = false;
    private boolean mLocalesChanged = false;

    @ViewDebug.ExportedProperty(category = "text")
    private int mGravity = Gravity.TOP | Gravity.START;
@@ -2817,32 +2819,58 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
    }

    /**
     * Get the default {@link Locale} of the text in this TextView.
     * @return the default {@link Locale} of the text in this TextView.
     * Get the default primary {@link Locale} of the text in this TextView. This will always be
     * the first member of {@link #getTextLocales()}.
     * @return the default primary {@link Locale} of the text in this TextView.
     */
    @NonNull
    public Locale getTextLocale() {
        return mTextPaint.getTextLocale();
    }

    /**
     * Set the default {@link Locale} of the text in this TextView to the given value. This value
     * is used to choose appropriate typefaces for ambiguous characters. Typically used for CJK
     * locales to disambiguate Hanzi/Kanji/Hanja characters.
     * Get the default {@link LocaleList} of the text in this TextView.
     * @return the default {@link LocaleList} of the text in this TextView.
     */
    @NonNull @Size(min=1)
    public LocaleList getTextLocales() {
        return mTextPaint.getTextLocales();
    }

    /**
     * Set the default {@link LocaleList} of the text in this TextView to a one-member list
     * containing just the given value.
     *
     * @param locale the {@link Locale} for drawing text, must not be null.
     *
     * @see Paint#setTextLocale
     * @see #setTextLocales
     */
    public void setTextLocale(Locale locale) {
        mLocaleChanged = true;
    public void setTextLocale(@NonNull Locale locale) {
        mLocalesChanged = true;
        mTextPaint.setTextLocale(locale);
    }

    /**
     * Set the default {@link LocaleList} of the text in this TextView to the given value.
     *
     * This value is used to choose appropriate typefaces for ambiguous characters (typically used
     * for CJK locales to disambiguate Hanzi/Kanji/Hanja characters). It also affects
     * other aspects of text display, including line breaking.
     *
     * @param locales the {@link LocaleList} for drawing text, must not be null or empty.
     *
     * @see Paint#setTextLocales
     */
    public void setTextLocales(@NonNull @Size(min=1) LocaleList locales) {
        mLocalesChanged = true;
        mTextPaint.setTextLocales(locales);
    }

    @Override
    protected void onConfigurationChanged(Configuration newConfig) {
        super.onConfigurationChanged(newConfig);
        if (!mLocaleChanged) {
            mTextPaint.setTextLocale(Locale.getDefault());
        if (!mLocalesChanged) {
            mTextPaint.setTextLocales(LocaleList.getDefault());
        }
    }

+62 −26
Original line number Diff line number Diff line
@@ -17,10 +17,13 @@
package android.graphics;

import android.annotation.ColorInt;
import android.annotation.NonNull;
import android.annotation.Size;
import android.text.GraphicsOperations;
import android.text.SpannableString;
import android.text.SpannedString;
import android.text.TextUtils;
import android.util.LocaleList;

import java.util.Locale;

@@ -50,7 +53,7 @@ public class Paint {
    private float       mCompatScaling;
    private float       mInvCompatScaling;

    private Locale      mLocale;
    private LocaleList  mLocales;
    private String      mFontFeatureSettings;

    /**
@@ -434,7 +437,7 @@ public class Paint {
        // setHinting(DisplayMetrics.DENSITY_DEVICE >= DisplayMetrics.DENSITY_TV
        //        ? HINTING_OFF : HINTING_ON);
        mCompatScaling = mInvCompatScaling = 1;
        setTextLocale(Locale.getDefault());
        setTextLocales(LocaleList.getDefault());
    }

    /**
@@ -474,7 +477,7 @@ public class Paint {
        mInvCompatScaling = 1;

        mBidiFlags = BIDI_DEFAULT_LTR;
        setTextLocale(Locale.getDefault());
        setTextLocales(LocaleList.getDefault());
        setElegantTextHeight(false);
        mFontFeatureSettings = null;
    }
@@ -512,7 +515,7 @@ public class Paint {
        mInvCompatScaling = paint.mInvCompatScaling;

        mBidiFlags = paint.mBidiFlags;
        mLocale = paint.mLocale;
        mLocales = paint.mLocales;
        mFontFeatureSettings = paint.mFontFeatureSettings;
    }

@@ -1174,47 +1177,80 @@ public class Paint {
    }

    /**
     * Get the text Locale.
     * Get the text's primary Locale. Note that this is not all of the locale-related information
     * Paint has. Use {@link #getTextLocales()} to get the complete list.
     *
     * @return the paint's Locale used for drawing text, never null.
     * @return the paint's primary Locale used for drawing text, never null.
     */
    @NonNull
    public Locale getTextLocale() {
        return mLocale;
        return mLocales.getPrimary();
    }

    /**
     * Set the text locale.
     * Get the text locale list.
     *
     * The text locale affects how the text is drawn for some languages.
     * @return the paint's LocaleList used for drawing text, never null or empty.
     */
    @NonNull @Size(min=1)
    public LocaleList getTextLocales() {
        return mLocales;
    }

    /**
     * Set the text locale list to a one-member list consisting of just the locale.
     *
     * See {@link #setTextLocales(LocaleList)} for how the locale list affects
     * the way the text is drawn for some languages.
     *
     * @param locale the paint's locale value for drawing text, must not be null.
     */
    public void setTextLocale(@NonNull Locale locale) {
        if (locale == null) {
            throw new IllegalArgumentException("locale cannot be null");
        }
        if (mLocales != null && mLocales.size() == 1 && locale.equals(mLocales.getPrimary())) {
            return;
        }
        mLocales = new LocaleList(locale);
        native_setTextLocale(mNativePaint, locale.toString());
    }

    /**
     * Set the text locale list.
     *
     * For example, if the locale is {@link Locale#CHINESE} or {@link Locale#CHINA},
     * The text locale list affects how the text is drawn for some languages.
     *
     * For example, if the locale list contains {@link Locale#CHINESE} or {@link Locale#CHINA},
     * then the text renderer will prefer to draw text using a Chinese font. Likewise,
     * if the locale is {@link Locale#JAPANESE} or {@link Locale#JAPAN}, then the text
     * renderer will prefer to draw text using a Japanese font.
     * if the locale list contains {@link Locale#JAPANESE} or {@link Locale#JAPAN}, then the text
     * renderer will prefer to draw text using a Japanese font. If the locale list contains both,
     * the order those locales appear in the list is considered for deciding the font.
     *
     * This distinction is important because Chinese and Japanese text both use many
     * of the same Unicode code points but their appearance is subtly different for
     * each language.
     *
     * By default, the text locale is initialized to the system locale (as returned
     * by {@link Locale#getDefault}). This assumes that the text to be rendered will
     * most likely be in the user's preferred language.
     * By default, the text locale list is initialized to a one-member list just containing the
     * system locale (as returned by {@link LocaleList#getDefault()}). This assumes that the text to
     * be rendered will most likely be in the user's preferred language.
     *
     * If the actual language of the text is known, then it can be provided to the
     * text renderer using this method. The text renderer may attempt to guess the
     * If the actual language or languages of the text is/are known, then they can be provided to
     * the text renderer using this method. The text renderer may attempt to guess the
     * language script based on the contents of the text to be drawn independent of
     * the text locale here. Specifying the text locale just helps it do a better
     * job in certain ambiguous cases
     * the text locale here. Specifying the text locales just helps it do a better
     * job in certain ambiguous cases.
     *
     * @param locale the paint's locale value for drawing text, must not be null.
     * @param locales the paint's locale list for drawing text, must not be null or empty.
     */
    public void setTextLocale(Locale locale) {
        if (locale == null) {
            throw new IllegalArgumentException("locale cannot be null");
    public void setTextLocales(@NonNull @Size(min=1) LocaleList locales) {
        if (locales == null || locales.isEmpty()) {
            throw new IllegalArgumentException("locales cannot be null or empty");
        }
        if (locale.equals(mLocale)) return;
        mLocale = locale;
        native_setTextLocale(mNativePaint, locale.toString());
        if (locales.equals(mLocales)) return;
        mLocales = locales;
        // TODO: Pass the whole LocaleList to native code
        native_setTextLocale(mNativePaint, locales.getPrimary().toString());
    }

    /**