blob: abbd793dcb2a3f85cbca97062f66044a1be1238b [file] [log] [blame]
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001/*
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
17package android.text.style;
18
19import android.content.Context;
20import android.content.res.ColorStateList;
21import android.content.res.TypedArray;
22import android.graphics.Typeface;
23import android.os.Parcel;
24import android.text.ParcelableSpan;
25import android.text.TextPaint;
26import android.text.TextUtils;
27
28/**
29 * Sets the text color, size, style, and typeface to match a TextAppearance
30 * resource.
31 */
32public 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 */
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,
Gilles Debunne0f9ae272011-04-27 14:25:54 -070054 * <code>android.R.styleable.Theme_textColorPrimary</code>.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080055 */
Gilles Debunne0f9ae272011-04-27 14:25:54 -070056 public TextAppearanceSpan(Context context, int appearance, int colorList) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080057 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);
Raph Leviend570e892012-05-09 11:45:34 -070071 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);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080076
Raph Leviend570e892012-05-09 11:45:34 -070077 switch (tf) {
78 case 1:
79 mTypeface = "sans";
80 break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080081
Raph Leviend570e892012-05-09 11:45:34 -070082 case 2:
83 mTypeface = "serif";
84 break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080085
Raph Leviend570e892012-05-09 11:45:34 -070086 case 3:
87 mTypeface = "monospace";
88 break;
89
90 default:
91 mTypeface = null;
92 break;
93 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080094 }
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 */
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
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
138 public int getSpanTypeId() {
Alan Viverettea70d4a92015-06-02 16:11:00 -0700139 return getSpanTypeIdInternal();
140 }
141
142 /** @hide */
143 public int getSpanTypeIdInternal() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800144 return TextUtils.TEXT_APPEARANCE_SPAN;
145 }
146
147 public int describeContents() {
148 return 0;
149 }
150
151 public void writeToParcel(Parcel dest, int flags) {
Alan Viverettea70d4a92015-06-02 16:11:00 -0700152 writeToParcelInternal(dest, flags);
153 }
154
155 /** @hide */
156 public void writeToParcelInternal(Parcel dest, int flags) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800157 dest.writeString(mTypeface);
158 dest.writeInt(mStyle);
159 dest.writeInt(mTextSize);
160 if (mTextColor != null) {
161 dest.writeInt(1);
162 mTextColor.writeToParcel(dest, flags);
163 } else {
164 dest.writeInt(0);
165 }
166 if (mTextColorLink != null) {
167 dest.writeInt(1);
168 mTextColorLink.writeToParcel(dest, flags);
169 } else {
170 dest.writeInt(0);
171 }
172 }
173
174 /**
175 * Returns the typeface family specified by this span, or <code>null</code>
176 * if it does not specify one.
177 */
178 public String getFamily() {
179 return mTypeface;
180 }
181
182 /**
183 * Returns the text color specified by this span, or <code>null</code>
184 * if it does not specify one.
185 */
186 public ColorStateList getTextColor() {
187 return mTextColor;
188 }
189
190 /**
191 * Returns the link color specified by this span, or <code>null</code>
192 * if it does not specify one.
193 */
194 public ColorStateList getLinkTextColor() {
195 return mTextColorLink;
196 }
197
198 /**
199 * Returns the text size specified by this span, or <code>-1</code>
200 * if it does not specify one.
201 */
202 public int getTextSize() {
203 return mTextSize;
204 }
205
206 /**
207 * Returns the text style specified by this span, or <code>0</code>
208 * if it does not specify one.
209 */
210 public int getTextStyle() {
211 return mStyle;
212 }
213
214 @Override
215 public void updateDrawState(TextPaint ds) {
216 updateMeasureState(ds);
217
218 if (mTextColor != null) {
219 ds.setColor(mTextColor.getColorForState(ds.drawableState, 0));
220 }
221
222 if (mTextColorLink != null) {
Fabrice Di Megliob8503eb2011-08-09 18:18:27 -0700223 ds.linkColor = mTextColorLink.getColorForState(ds.drawableState, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800224 }
225 }
226
227 @Override
228 public void updateMeasureState(TextPaint ds) {
229 if (mTypeface != null || mStyle != 0) {
230 Typeface tf = ds.getTypeface();
231 int style = 0;
232
233 if (tf != null) {
234 style = tf.getStyle();
235 }
236
237 style |= mStyle;
238
239 if (mTypeface != null) {
240 tf = Typeface.create(mTypeface, style);
241 } else if (tf == null) {
242 tf = Typeface.defaultFromStyle(style);
243 } else {
244 tf = Typeface.create(tf, style);
245 }
246
247 int fake = style & ~tf.getStyle();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800248
249 if ((fake & Typeface.BOLD) != 0) {
250 ds.setFakeBoldText(true);
251 }
252
253 if ((fake & Typeface.ITALIC) != 0) {
254 ds.setTextSkewX(-0.25f);
255 }
256
257 ds.setTypeface(tf);
258 }
259
260 if (mTextSize > 0) {
261 ds.setTextSize(mTextSize);
262 }
263 }
264}