/* * Copyright (C) 2008 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package android.text.style; import android.content.Context; import android.content.res.ColorStateList; import android.content.res.TypedArray; import android.graphics.Typeface; import android.os.Parcel; import android.text.ParcelableSpan; import android.text.TextPaint; import android.text.TextUtils; /** * Sets the text color, size, style, and typeface to match a TextAppearance * resource. */ public class TextAppearanceSpan extends MetricAffectingSpan implements ParcelableSpan { private final String mTypeface; private final int mStyle; private final int mTextSize; private final ColorStateList mTextColor; private final ColorStateList mTextColorLink; /** * Uses the specified TextAppearance resource to determine the * text appearance. The appearance should be, for example, * android.R.style.TextAppearance_Small. */ public TextAppearanceSpan(Context context, int appearance) { this(context, appearance, -1); } /** * Uses the specified TextAppearance resource to determine the * text appearance, and the specified text color resource * to determine the color. The appearance should be, * for example, android.R.style.TextAppearance_Small, * and the colorList should be, for example, * android.R.styleable.Theme_textColorPrimary. */ public TextAppearanceSpan(Context context, int appearance, int colorList) { ColorStateList textColor; TypedArray a = context.obtainStyledAttributes(appearance, com.android.internal.R.styleable.TextAppearance); textColor = a.getColorStateList(com.android.internal.R.styleable. TextAppearance_textColor); mTextColorLink = a.getColorStateList(com.android.internal.R.styleable. TextAppearance_textColorLink); mTextSize = a.getDimensionPixelSize(com.android.internal.R.styleable. TextAppearance_textSize, -1); mStyle = a.getInt(com.android.internal.R.styleable.TextAppearance_textStyle, 0); String family = a.getString(com.android.internal.R.styleable.TextAppearance_fontFamily); if (family != null) { mTypeface = family; } else { int tf = a.getInt(com.android.internal.R.styleable.TextAppearance_typeface, 0); switch (tf) { case 1: mTypeface = "sans"; break; case 2: mTypeface = "serif"; break; case 3: mTypeface = "monospace"; break; default: mTypeface = null; break; } } a.recycle(); if (colorList >= 0) { a = context.obtainStyledAttributes(com.android.internal.R.style.Theme, com.android.internal.R.styleable.Theme); textColor = a.getColorStateList(colorList); a.recycle(); } mTextColor = textColor; } /** * Makes text be drawn with the specified typeface, size, style, * and colors. */ public TextAppearanceSpan(String family, int style, int size, ColorStateList color, ColorStateList linkColor) { mTypeface = family; mStyle = style; mTextSize = size; mTextColor = color; mTextColorLink = linkColor; } public TextAppearanceSpan(Parcel src) { mTypeface = src.readString(); mStyle = src.readInt(); mTextSize = src.readInt(); if (src.readInt() != 0) { mTextColor = ColorStateList.CREATOR.createFromParcel(src); } else { mTextColor = null; } if (src.readInt() != 0) { mTextColorLink = ColorStateList.CREATOR.createFromParcel(src); } else { mTextColorLink = null; } } public int getSpanTypeId() { return TextUtils.TEXT_APPEARANCE_SPAN; } public int describeContents() { return 0; } public void writeToParcel(Parcel dest, int flags) { dest.writeString(mTypeface); dest.writeInt(mStyle); dest.writeInt(mTextSize); if (mTextColor != null) { dest.writeInt(1); mTextColor.writeToParcel(dest, flags); } else { dest.writeInt(0); } if (mTextColorLink != null) { dest.writeInt(1); mTextColorLink.writeToParcel(dest, flags); } else { dest.writeInt(0); } } /** * Returns the typeface family specified by this span, or null * if it does not specify one. */ public String getFamily() { return mTypeface; } /** * Returns the text color specified by this span, or null * if it does not specify one. */ public ColorStateList getTextColor() { return mTextColor; } /** * Returns the link color specified by this span, or null * if it does not specify one. */ public ColorStateList getLinkTextColor() { return mTextColorLink; } /** * Returns the text size specified by this span, or -1 * if it does not specify one. */ public int getTextSize() { return mTextSize; } /** * Returns the text style specified by this span, or 0 * if it does not specify one. */ public int getTextStyle() { return mStyle; } @Override public void updateDrawState(TextPaint ds) { updateMeasureState(ds); if (mTextColor != null) { ds.setColor(mTextColor.getColorForState(ds.drawableState, 0)); } if (mTextColorLink != null) { ds.linkColor = mTextColorLink.getColorForState(ds.drawableState, 0); } } @Override public void updateMeasureState(TextPaint ds) { if (mTypeface != null || mStyle != 0) { Typeface tf = ds.getTypeface(); int style = 0; if (tf != null) { style = tf.getStyle(); } style |= mStyle; if (mTypeface != null) { tf = Typeface.create(mTypeface, style); } else if (tf == null) { tf = Typeface.defaultFromStyle(style); } else { tf = Typeface.create(tf, style); } int fake = style & ~tf.getStyle(); if ((fake & Typeface.BOLD) != 0) { ds.setFakeBoldText(true); } if ((fake & Typeface.ITALIC) != 0) { ds.setTextSkewX(-0.25f); } ds.setTypeface(tf); } if (mTextSize > 0) { ds.setTextSize(mTextSize); } } }