Merge "Add LocaleList support to Paint and TextView."

This commit is contained in:
Roozbeh Pournader
2015-09-01 21:14:11 +00:00
committed by Android (Google) Code Review
5 changed files with 133 additions and 37 deletions

View File

@@ -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);

View File

@@ -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);

View File

@@ -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;
}
}

View File

@@ -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());
}
}

View File

@@ -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.
*
* For example, if the locale is {@link Locale#CHINESE} or {@link Locale#CHINA},
* 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.
*
* 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());
}
/**