Loading api/current.txt +2 −0 Original line number Diff line number Diff line Loading @@ -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); core/java/android/text/style/TypefaceSpan.java +84 −25 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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 Loading Loading @@ -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); Loading @@ -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); } } docs/html/reference/images/text/style/typefacespan.png +1004 B (8.55 KiB) Loading image diff... Loading
api/current.txt +2 −0 Original line number Diff line number Diff line Loading @@ -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);
core/java/android/text/style/TypefaceSpan.java +84 −25 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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 Loading Loading @@ -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); Loading @@ -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); } }