• Home
  • History
  • Annotate
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2008 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.content.Context;
20 import android.content.res.ColorStateList;
21 import android.content.res.TypedArray;
22 import android.graphics.Typeface;
23 import android.os.Parcel;
24 import android.text.ParcelableSpan;
25 import android.text.TextPaint;
26 import android.text.TextUtils;
27 
28 /**
29  * Sets the text color, size, style, and typeface to match a TextAppearance
30  * resource.
31  */
32 public class TextAppearanceSpan extends MetricAffectingSpan implements ParcelableSpan {
33     private final String mTypeface;
34     private final int mStyle;
35     private final int mTextSize;
36     private final ColorStateList mTextColor;
37     private final ColorStateList mTextColorLink;
38 
39     /**
40      * Uses the specified TextAppearance resource to determine the
41      * text appearance.  The <code>appearance</code> should be, for example,
42      * <code>android.R.style.TextAppearance_Small</code>.
43      */
TextAppearanceSpan(Context context, int appearance)44     public TextAppearanceSpan(Context context, int appearance) {
45         this(context, appearance, -1);
46     }
47 
48     /**
49      * Uses the specified TextAppearance resource to determine the
50      * text appearance, and the specified text color resource
51      * to determine the color.  The <code>appearance</code> should be,
52      * for example, <code>android.R.style.TextAppearance_Small</code>,
53      * and the <code>colorList</code> should be, for example,
54      * <code>android.R.styleable.Theme_textColorPrimary</code>.
55      */
TextAppearanceSpan(Context context, int appearance, int colorList)56     public TextAppearanceSpan(Context context, int appearance, int colorList) {
57         ColorStateList textColor;
58 
59         TypedArray a =
60             context.obtainStyledAttributes(appearance,
61                                            com.android.internal.R.styleable.TextAppearance);
62 
63         textColor = a.getColorStateList(com.android.internal.R.styleable.
64                                         TextAppearance_textColor);
65         mTextColorLink = a.getColorStateList(com.android.internal.R.styleable.
66                                         TextAppearance_textColorLink);
67         mTextSize = a.getDimensionPixelSize(com.android.internal.R.styleable.
68                                         TextAppearance_textSize, -1);
69 
70         mStyle = a.getInt(com.android.internal.R.styleable.TextAppearance_textStyle, 0);
71         String family = a.getString(com.android.internal.R.styleable.TextAppearance_fontFamily);
72         if (family != null) {
73             mTypeface = family;
74         } else {
75             int tf = a.getInt(com.android.internal.R.styleable.TextAppearance_typeface, 0);
76 
77             switch (tf) {
78                 case 1:
79                     mTypeface = "sans";
80                     break;
81 
82                 case 2:
83                     mTypeface = "serif";
84                     break;
85 
86                 case 3:
87                     mTypeface = "monospace";
88                     break;
89 
90                 default:
91                     mTypeface = null;
92                     break;
93             }
94         }
95 
96         a.recycle();
97 
98         if (colorList >= 0) {
99             a = context.obtainStyledAttributes(com.android.internal.R.style.Theme,
100                                             com.android.internal.R.styleable.Theme);
101 
102             textColor = a.getColorStateList(colorList);
103             a.recycle();
104         }
105 
106         mTextColor = textColor;
107     }
108 
109     /**
110      * Makes text be drawn with the specified typeface, size, style,
111      * and colors.
112      */
TextAppearanceSpan(String family, int style, int size, ColorStateList color, ColorStateList linkColor)113     public TextAppearanceSpan(String family, int style, int size,
114                               ColorStateList color, ColorStateList linkColor) {
115         mTypeface = family;
116         mStyle = style;
117         mTextSize = size;
118         mTextColor = color;
119         mTextColorLink = linkColor;
120     }
121 
TextAppearanceSpan(Parcel src)122     public TextAppearanceSpan(Parcel src) {
123         mTypeface = src.readString();
124         mStyle = src.readInt();
125         mTextSize = src.readInt();
126         if (src.readInt() != 0) {
127             mTextColor = ColorStateList.CREATOR.createFromParcel(src);
128         } else {
129             mTextColor = null;
130         }
131         if (src.readInt() != 0) {
132             mTextColorLink = ColorStateList.CREATOR.createFromParcel(src);
133         } else {
134             mTextColorLink = null;
135         }
136     }
137 
getSpanTypeId()138     public int getSpanTypeId() {
139         return TextUtils.TEXT_APPEARANCE_SPAN;
140     }
141 
describeContents()142     public int describeContents() {
143         return 0;
144     }
145 
writeToParcel(Parcel dest, int flags)146     public void writeToParcel(Parcel dest, int flags) {
147         dest.writeString(mTypeface);
148         dest.writeInt(mStyle);
149         dest.writeInt(mTextSize);
150         if (mTextColor != null) {
151             dest.writeInt(1);
152             mTextColor.writeToParcel(dest, flags);
153         } else {
154             dest.writeInt(0);
155         }
156         if (mTextColorLink != null) {
157             dest.writeInt(1);
158             mTextColorLink.writeToParcel(dest, flags);
159         } else {
160             dest.writeInt(0);
161         }
162     }
163 
164     /**
165      * Returns the typeface family specified by this span, or <code>null</code>
166      * if it does not specify one.
167      */
getFamily()168     public String getFamily() {
169         return mTypeface;
170     }
171 
172     /**
173      * Returns the text color specified by this span, or <code>null</code>
174      * if it does not specify one.
175      */
getTextColor()176     public ColorStateList getTextColor() {
177         return mTextColor;
178     }
179 
180     /**
181      * Returns the link color specified by this span, or <code>null</code>
182      * if it does not specify one.
183      */
getLinkTextColor()184     public ColorStateList getLinkTextColor() {
185         return mTextColorLink;
186     }
187 
188     /**
189      * Returns the text size specified by this span, or <code>-1</code>
190      * if it does not specify one.
191      */
getTextSize()192     public int getTextSize() {
193         return mTextSize;
194     }
195 
196     /**
197      * Returns the text style specified by this span, or <code>0</code>
198      * if it does not specify one.
199      */
getTextStyle()200     public int getTextStyle() {
201         return mStyle;
202     }
203 
204     @Override
updateDrawState(TextPaint ds)205     public void updateDrawState(TextPaint ds) {
206         updateMeasureState(ds);
207 
208         if (mTextColor != null) {
209             ds.setColor(mTextColor.getColorForState(ds.drawableState, 0));
210         }
211 
212         if (mTextColorLink != null) {
213             ds.linkColor = mTextColorLink.getColorForState(ds.drawableState, 0);
214         }
215     }
216 
217     @Override
updateMeasureState(TextPaint ds)218     public void updateMeasureState(TextPaint ds) {
219         if (mTypeface != null || mStyle != 0) {
220             Typeface tf = ds.getTypeface();
221             int style = 0;
222 
223             if (tf != null) {
224                 style = tf.getStyle();
225             }
226 
227             style |= mStyle;
228 
229             if (mTypeface != null) {
230                 tf = Typeface.create(mTypeface, style);
231             } else if (tf == null) {
232                 tf = Typeface.defaultFromStyle(style);
233             } else {
234                 tf = Typeface.create(tf, style);
235             }
236 
237             int fake = style & ~tf.getStyle();
238 
239             if ((fake & Typeface.BOLD) != 0) {
240                 ds.setFakeBoldText(true);
241             }
242 
243             if ((fake & Typeface.ITALIC) != 0) {
244                 ds.setTextSkewX(-0.25f);
245             }
246 
247             ds.setTypeface(tf);
248         }
249 
250         if (mTextSize > 0) {
251             ds.setTextSize(mTextSize);
252         }
253     }
254 }
255