Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 961b465a authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Allowing Typeface as a param in TypefaceSpan."

parents 1d84b173 57c8b961
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -44496,10 +44496,12 @@ package android.text.style {
  public class TypefaceSpan extends android.text.style.MetricAffectingSpan implements android.text.ParcelableSpan {
    ctor public TypefaceSpan(java.lang.String);
    ctor public TypefaceSpan(android.graphics.Typeface);
    ctor public TypefaceSpan(android.os.Parcel);
    method public int describeContents();
    method public java.lang.String getFamily();
    method public int getSpanTypeId();
    method public android.graphics.Typeface getTypeface();
    method public void updateDrawState(android.text.TextPaint);
    method public void updateMeasureState(android.text.TextPaint);
    method public void writeToParcel(android.os.Parcel, int);
+84 −25
Original line number Diff line number Diff line
@@ -17,6 +17,8 @@
package android.text.style;

import android.annotation.NonNull;
import android.annotation.Nullable;
import android.graphics.LeakyTypefaceStorage;
import android.graphics.Paint;
import android.graphics.Typeface;
import android.os.Parcel;
@@ -25,33 +27,69 @@ import android.text.TextPaint;
import android.text.TextUtils;

/**
 * Changes the typeface family of the text to which the span is attached. Examples of typeface
 * family include "monospace", "serif", and "sans-serif".
 * Span that updates the typeface of the text it's attached to. The <code>TypefaceSpan</code> can
 * be constructed either based on a font family or based on a <code>Typeface</code>. When
 * {@link #TypefaceSpan(String)} is used, the previous style of the <code>TextView</code> is kept.
 * When {@link #TypefaceSpan(Typeface)} is used, the <code>Typeface</code> style replaces the
 * <code>TextView</code>'s style.
 * <p>
 * For example, change the typeface of a text to "monospace" like this:
 * For example, let's consider a <code>TextView</code> with
 * <code>android:textStyle="italic"</code> and a typeface created based on a font from resources,
 * with a bold style. When applying a <code>TypefaceSpan</code> based the typeface, the text will
 * only keep the bold style, overriding the <code>TextView</code>'s textStyle. When applying a
 * <code>TypefaceSpan</code> based on a font family: "monospace", the resulted text will keep the
 * italic style.
 * <pre>
 * SpannableString string = new SpannableString("Text with typeface span");
 * string.setSpan(new TypefaceSpan("monospace"), 10, 18, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
 * Typeface myTypeface = Typeface.create(ResourcesCompat.getFont(context, R.font.acme),
 * Typeface.BOLD);
 * SpannableString string = new SpannableString("Text with typeface span.");
 * string.setSpan(new TypefaceSpan(myTypeface), 10, 18, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
 * string.setSpan(new TypefaceSpan("monospace"), 19, 22, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
 * </pre>
 * <img src="{@docRoot}reference/android/images/text/style/typefacespan.png" />
 * <figcaption>Text with "monospace" typeface family.</figcaption>
 * <figcaption>Text with <code>TypefaceSpan</code>s constructed based on a font from resource and
 * from a font family.</figcaption>
 */
public class TypefaceSpan extends MetricAffectingSpan implements ParcelableSpan {

    @Nullable
    private final String mFamily;

    @Nullable
    private final Typeface mTypeface;

    /**
     * Constructs a {@link TypefaceSpan} based on a font family.
     * Constructs a {@link TypefaceSpan} based on the font family. The previous style of the
     * TextPaint is kept. If the font family is null, the text paint is not modified.
     *
     * @param family The font family for this typeface.  Examples include
     *               "monospace", "serif", and "sans-serif".
     *               "monospace", "serif", and "sans-serif"
     */
    public TypefaceSpan(String family) {
        mFamily = family;
    public TypefaceSpan(@Nullable String family) {
        this(family, null);
    }

    /**
     * Constructs a {@link TypefaceSpan} from a {@link Typeface}. The previous style of the
     * TextPaint is overridden and the style of the typeface is used.
     *
     * @param typeface the typeface
     */
    public TypefaceSpan(@NonNull Typeface typeface) {
        this(null, typeface);
    }

    /**
     * Constructs a {@link TypefaceSpan} from a  parcel.
     */
    public TypefaceSpan(@NonNull Parcel src) {
        mFamily = src.readString();
        mTypeface = LeakyTypefaceStorage.readTypefaceFromParcel(src);
    }

    private TypefaceSpan(@Nullable String family, @Nullable Typeface typeface) {
        mFamily = family;
        mTypeface = typeface;
    }

    @Override
@@ -79,37 +117,59 @@ public class TypefaceSpan extends MetricAffectingSpan implements ParcelableSpan
    @Override
    public void writeToParcelInternal(@NonNull Parcel dest, int flags) {
        dest.writeString(mFamily);
        LeakyTypefaceStorage.writeTypefaceToParcel(mTypeface, dest);
    }

    /**
     * Returns the font family name.
     * Returns the font family name set in the span.
     *
     * @return the font family name
     * @see #TypefaceSpan(String)
     */
    @Nullable
    public String getFamily() {
        return mFamily;
    }

    /**
     * Returns the typeface set in the span.
     *
     * @return the typeface set
     * @see #TypefaceSpan(Typeface)
     */
    @Nullable
    public Typeface getTypeface() {
        return mTypeface;
    }

    @Override
    public void updateDrawState(@NonNull TextPaint textPaint) {
        apply(textPaint, mFamily);
    public void updateDrawState(@NonNull TextPaint ds) {
        updateTypeface(ds);
    }

    @Override
    public void updateMeasureState(@NonNull TextPaint textPaint) {
        apply(textPaint, mFamily);
    public void updateMeasureState(@NonNull TextPaint paint) {
        updateTypeface(paint);
    }

    private static void apply(@NonNull Paint paint, String family) {
        int oldStyle;
    private void updateTypeface(@NonNull Paint paint) {
        if (mTypeface != null) {
            paint.setTypeface(mTypeface);
        } else if (mFamily != null) {
            applyFontFamily(paint, mFamily);
        }
    }

    private void applyFontFamily(@NonNull Paint paint, @NonNull String family) {
        int style;
        Typeface old = paint.getTypeface();
        if (old == null) {
            oldStyle = 0;
            style = Typeface.NORMAL;
        } else {
            oldStyle = old.getStyle();
            style = old.getStyle();
        }

        Typeface tf = Typeface.create(family, oldStyle);
        int fake = oldStyle & ~tf.getStyle();
        final Typeface styledTypeface = Typeface.create(family, style);
        int fake = style & ~styledTypeface.getStyle();

        if ((fake & Typeface.BOLD) != 0) {
            paint.setFakeBoldText(true);
@@ -118,7 +178,6 @@ public class TypefaceSpan extends MetricAffectingSpan implements ParcelableSpan
        if ((fake & Typeface.ITALIC) != 0) {
            paint.setTextSkewX(-0.25f);
        }

        paint.setTypeface(tf);
        paint.setTypeface(styledTypeface);
    }
}
+1004 B (8.55 KiB)
Loading image diff...