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