diff options
author | Roozbeh Pournader <roozbeh@google.com> | 2015-09-01 21:14:11 +0000 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2015-09-01 21:14:11 +0000 |
commit | 008d6d034ea68a7ccc5b7c454f642fcaaf9dc2cb (patch) | |
tree | f29dff4272ddc12266117b31f8643b8646aebde2 | |
parent | 6b49d300346d130d2681cbd3de7165989c3a33f2 (diff) | |
parent | a23748a9ff9ddc8b490fc31752afa9b955d5e156 (diff) |
Merge "Add LocaleList support to Paint and TextView."
-rw-r--r-- | api/current.txt | 5 | ||||
-rw-r--r-- | api/system-current.txt | 5 | ||||
-rw-r--r-- | core/java/android/util/LocaleList.java | 22 | ||||
-rw-r--r-- | core/java/android/widget/TextView.java | 50 | ||||
-rw-r--r-- | graphics/java/android/graphics/Paint.java | 88 |
5 files changed, 133 insertions, 37 deletions
diff --git a/api/current.txt b/api/current.txt index b2966729ffaa..b60bf1f92929 100644 --- a/api/current.txt +++ b/api/current.txt @@ -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); diff --git a/api/system-current.txt b/api/system-current.txt index 7cc66cf1ab3f..a0a5918dabca 100644 --- a/api/system-current.txt +++ b/api/system-current.txt @@ -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); diff --git a/core/java/android/util/LocaleList.java b/core/java/android/util/LocaleList.java index afae9aceda17..379651ef86f8 100644 --- a/core/java/android/util/LocaleList.java +++ b/core/java/android/util/LocaleList.java @@ -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; + } } diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java index 7a6437724e2f..61402abcece7 100644 --- a/core/java/android/widget/TextView.java +++ b/core/java/android/widget/TextView.java @@ -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()); } } diff --git a/graphics/java/android/graphics/Paint.java b/graphics/java/android/graphics/Paint.java index c5d68bd230c1..ce35b871b8db 100644 --- a/graphics/java/android/graphics/Paint.java +++ b/graphics/java/android/graphics/Paint.java @@ -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()); } /** |