1 /*
2  * Copyright (C) 2012 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package android.text.style;
18 
19 import android.annotation.NonNull;
20 import android.annotation.Nullable;
21 import android.graphics.Paint;
22 import android.os.LocaleList;
23 import android.os.Parcel;
24 import android.text.ParcelableSpan;
25 import android.text.TextPaint;
26 import android.text.TextUtils;
27 
28 import com.android.internal.util.Preconditions;
29 
30 import java.util.Locale;
31 
32 /**
33  * Changes the {@link Locale} of the text to which the span is attached.
34  */
35 public class LocaleSpan extends MetricAffectingSpan implements ParcelableSpan {
36     @NonNull
37     private final LocaleList mLocales;
38 
39     /**
40      * Creates a {@link LocaleSpan} from a well-formed {@link Locale}.  Note that only
41      * {@link Locale} objects that can be created by {@link Locale#forLanguageTag(String)} are
42      * supported.
43      *
44      * <p><b>Caveat:</b> Do not specify any {@link Locale} object that cannot be created by
45      * {@link Locale#forLanguageTag(String)}.  {@code new Locale(" a ", " b c", " d")} is an
46      * example of such a malformed {@link Locale} object.</p>
47      *
48      * @param locale The {@link Locale} of the text to which the span is attached.
49      *
50      * @see #LocaleSpan(LocaleList)
51      */
LocaleSpan(@ullable Locale locale)52     public LocaleSpan(@Nullable Locale locale) {
53         mLocales = locale == null ? LocaleList.getEmptyLocaleList() : new LocaleList(locale);
54     }
55 
56     /**
57      * Creates a {@link LocaleSpan} from {@link LocaleList}.
58      *
59      * @param locales The {@link LocaleList} of the text to which the span is attached.
60      * @throws NullPointerException if {@code locales} is null
61      */
LocaleSpan(@onNull LocaleList locales)62     public LocaleSpan(@NonNull LocaleList locales) {
63         Preconditions.checkNotNull(locales, "locales cannot be null");
64         mLocales = locales;
65     }
66 
LocaleSpan(Parcel source)67     public LocaleSpan(Parcel source) {
68         mLocales = LocaleList.CREATOR.createFromParcel(source);
69     }
70 
71     @Override
getSpanTypeId()72     public int getSpanTypeId() {
73         return getSpanTypeIdInternal();
74     }
75 
76     /** @hide */
getSpanTypeIdInternal()77     public int getSpanTypeIdInternal() {
78         return TextUtils.LOCALE_SPAN;
79     }
80 
81     @Override
describeContents()82     public int describeContents() {
83         return 0;
84     }
85 
86     @Override
writeToParcel(Parcel dest, int flags)87     public void writeToParcel(Parcel dest, int flags) {
88         writeToParcelInternal(dest, flags);
89     }
90 
91     /** @hide */
writeToParcelInternal(Parcel dest, int flags)92     public void writeToParcelInternal(Parcel dest, int flags) {
93         mLocales.writeToParcel(dest, flags);
94     }
95 
96     /**
97      * @return The {@link Locale} for this span.  If multiple locales are associated with this
98      * span, only the first locale is returned.  {@code null} if no {@link Locale} is specified.
99      *
100      * @see LocaleList#get(int)
101      * @see #getLocales()
102      */
103     @Nullable
getLocale()104     public Locale getLocale() {
105         return mLocales.get(0);
106     }
107 
108     /**
109      * @return The entire list of locales that are associated with this span.
110      */
111     @NonNull
getLocales()112     public LocaleList getLocales() {
113         return mLocales;
114     }
115 
116     @Override
updateDrawState(TextPaint ds)117     public void updateDrawState(TextPaint ds) {
118         apply(ds, mLocales);
119     }
120 
121     @Override
updateMeasureState(TextPaint paint)122     public void updateMeasureState(TextPaint paint) {
123         apply(paint, mLocales);
124     }
125 
apply(@onNull Paint paint, @NonNull LocaleList locales)126     private static void apply(@NonNull Paint paint, @NonNull LocaleList locales) {
127         paint.setTextLocales(locales);
128     }
129 
130     @Override
toString()131     public String toString() {
132         return "LocaleSpan{locales=" + getLocales() + '}';
133     }
134 }
135