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