TextAppearanceSpan.java revision 9066cfe9886ac131c34d59ed0e2d287b0e3c0087
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 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} 251