1 /*
2  * Copyright (C) 2022 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 
17 package android.view.inputmethod;
18 
19 import static android.graphics.Typeface.NORMAL;
20 
21 import android.annotation.ColorInt;
22 import android.annotation.IntRange;
23 import android.annotation.NonNull;
24 import android.annotation.Nullable;
25 import android.annotation.Px;
26 import android.graphics.Paint;
27 import android.graphics.Typeface;
28 import android.graphics.fonts.FontStyle;
29 import android.graphics.text.LineBreakConfig;
30 import android.inputmethodservice.InputMethodService;
31 import android.os.LocaleList;
32 import android.os.Parcel;
33 import android.os.Parcelable;
34 import android.text.Spanned;
35 import android.text.TextPaint;
36 import android.text.method.TransformationMethod;
37 import android.text.style.CharacterStyle;
38 import android.widget.TextView;
39 
40 import java.util.Objects;
41 
42 /**
43  * Information about text appearance in an editor, passed through
44  * {@link CursorAnchorInfo} for use by {@link InputMethodService}.
45  * @see TextView
46  * @see Paint
47  * @see CursorAnchorInfo.Builder#setTextAppearanceInfo(TextAppearanceInfo)
48  * @see CursorAnchorInfo#getTextAppearanceInfo()
49  */
50 public final class TextAppearanceInfo implements Parcelable {
51     /**
52      * The text size (in pixels) for current editor.
53      */
54     private final @Px float mTextSize;
55 
56     /**
57      * The {@link LocaleList} of the text.
58      */
59     @NonNull private final LocaleList mTextLocales;
60 
61     /**
62      * The font family name if the {@link Typeface} of the text is created from a system font
63      * family, otherwise this value should be null.
64      */
65     @Nullable private final String mSystemFontFamilyName;
66 
67     /**
68      * The weight of the text.
69      */
70     @IntRange(from = FontStyle.FONT_WEIGHT_UNSPECIFIED, to = FontStyle.FONT_WEIGHT_MAX)
71     private final int mTextFontWeight;
72 
73     /**
74      * The style (normal, bold, italic, bold|italic) of the text, see {@link Typeface}.
75      */
76     private final @Typeface.Style int mTextStyle;
77 
78     /**
79      * Whether the transformation method applied to the current editor is set to all caps.
80      */
81     private final boolean mAllCaps;
82 
83     /**
84      * The horizontal offset (in pixels) of the text shadow.
85      */
86     private final @Px float mShadowDx;
87 
88     /**
89      * The vertical offset (in pixels) of the text shadow.
90      */
91     private final @Px float mShadowDy;
92 
93     /**
94      * The blur radius (in pixels) of the text shadow.
95      */
96     private final @Px float mShadowRadius;
97 
98     /**
99      * The shadow color of the text shadow.
100      */
101     private final @ColorInt int mShadowColor;
102 
103     /**
104      * The elegant text height, especially for less compacted complex script text.
105      */
106     private final boolean mElegantTextHeight;
107 
108     /**
109      * Whether to expand linespacing based on fallback fonts.
110      */
111     private final boolean mFallbackLineSpacing;
112 
113     /**
114      * The text letter-spacing (in ems), which determines the spacing between characters.
115      */
116     private final float mLetterSpacing;
117 
118     /**
119      * The font feature settings.
120      */
121     @Nullable private final String mFontFeatureSettings;
122 
123     /**
124      * The font variation settings.
125      */
126     @Nullable private final String mFontVariationSettings;
127 
128     /**
129      * The line-break strategies for text wrapping.
130      */
131     private final @LineBreakConfig.LineBreakStyle int mLineBreakStyle;
132 
133     /**
134      * The line-break word strategies for text wrapping.
135      */
136     private final @LineBreakConfig.LineBreakWordStyle int mLineBreakWordStyle;
137 
138     /**
139      * The extent by which text should be stretched horizontally. Returns 1.0 if not specified.
140      */
141     private final float mTextScaleX;
142 
143     /**
144      * The color of the text selection highlight.
145      */
146     private final @ColorInt int mHighlightTextColor;
147 
148     /**
149      * The current text color of the editor.
150      */
151     private final @ColorInt int mTextColor;
152 
153     /**
154      *  The current color of the hint text.
155      */
156     private final @ColorInt int mHintTextColor;
157 
158     /**
159      * The text color used to paint the links in the editor.
160      */
161     private final @ColorInt int mLinkTextColor;
162 
TextAppearanceInfo(@onNull final TextAppearanceInfo.Builder builder)163     private TextAppearanceInfo(@NonNull final TextAppearanceInfo.Builder builder) {
164         mTextSize = builder.mTextSize;
165         mTextLocales = builder.mTextLocales;
166         mSystemFontFamilyName = builder.mSystemFontFamilyName;
167         mTextFontWeight = builder.mTextFontWeight;
168         mTextStyle = builder.mTextStyle;
169         mAllCaps = builder.mAllCaps;
170         mShadowDx = builder.mShadowDx;
171         mShadowDy = builder.mShadowDy;
172         mShadowRadius = builder.mShadowRadius;
173         mShadowColor = builder.mShadowColor;
174         mElegantTextHeight = builder.mElegantTextHeight;
175         mFallbackLineSpacing = builder.mFallbackLineSpacing;
176         mLetterSpacing = builder.mLetterSpacing;
177         mFontFeatureSettings = builder.mFontFeatureSettings;
178         mFontVariationSettings = builder.mFontVariationSettings;
179         mLineBreakStyle = builder.mLineBreakStyle;
180         mLineBreakWordStyle = builder.mLineBreakWordStyle;
181         mTextScaleX = builder.mTextScaleX;
182         mHighlightTextColor = builder.mHighlightTextColor;
183         mTextColor = builder.mTextColor;
184         mHintTextColor = builder.mHintTextColor;
185         mLinkTextColor = builder.mLinkTextColor;
186     }
187 
188     /**
189      * Creates a new instance of {@link TextAppearanceInfo} by extracting text appearance from the
190      * character before cursor in the target {@link TextView}.
191      * @param textView the target {@link TextView}.
192      * @return the new instance of {@link TextAppearanceInfo}.
193      * @hide
194      */
195     @NonNull
createFromTextView(@onNull TextView textView)196     public static TextAppearanceInfo createFromTextView(@NonNull TextView textView) {
197         final int selectionStart = textView.getSelectionStart();
198         final CharSequence text = textView.getText();
199         TextPaint textPaint = new TextPaint();
200         textPaint.set(textView.getPaint());    // Copy from textView
201         if (text instanceof Spanned && text.length() > 0 && selectionStart > 0) {
202             // Extract the CharacterStyle spans that changes text appearance in the character before
203             // cursor.
204             Spanned spannedText = (Spanned) text;
205             int lastCh = selectionStart - 1;
206             CharacterStyle[] spans = spannedText.getSpans(lastCh, lastCh, CharacterStyle.class);
207             if (spans != null) {
208                 for (CharacterStyle span: spans) {
209                     // Exclude spans that end at lastCh
210                     if (spannedText.getSpanStart(span) <= lastCh
211                             && lastCh < spannedText.getSpanEnd(span)) {
212                         span.updateDrawState(textPaint); // Override the TextPaint
213                     }
214                 }
215             }
216         }
217         Typeface typeface = textPaint.getTypeface();
218         String systemFontFamilyName = null;
219         int textWeight = FontStyle.FONT_WEIGHT_UNSPECIFIED;
220         int textStyle = Typeface.NORMAL;
221         if (typeface != null) {
222             systemFontFamilyName = typeface.getSystemFontFamilyName();
223             textWeight = typeface.getWeight();
224             textStyle = typeface.getStyle();
225         }
226         TextAppearanceInfo.Builder builder = new TextAppearanceInfo.Builder();
227         builder.setTextSize(textPaint.getTextSize())
228                 .setTextLocales(textPaint.getTextLocales())
229                 .setSystemFontFamilyName(systemFontFamilyName)
230                 .setTextFontWeight(textWeight)
231                 .setTextStyle(textStyle)
232                 .setShadowDx(textPaint.getShadowLayerDx())
233                 .setShadowDy(textPaint.getShadowLayerDy())
234                 .setShadowRadius(textPaint.getShadowLayerRadius())
235                 .setShadowColor(textPaint.getShadowLayerColor())
236                 .setElegantTextHeight(textPaint.isElegantTextHeight())
237                 .setLetterSpacing(textPaint.getLetterSpacing())
238                 .setFontFeatureSettings(textPaint.getFontFeatureSettings())
239                 .setFontVariationSettings(textPaint.getFontVariationSettings())
240                 .setTextScaleX(textPaint.getTextScaleX())
241                 // When there is a hint text (text length is 0), the text color should be the normal
242                 // text color rather than hint text color.
243                 .setTextColor(text.length() == 0
244                         ? textView.getCurrentTextColor() : textPaint.getColor())
245                 .setLinkTextColor(textPaint.linkColor)
246                 .setAllCaps(textView.isAllCaps())
247                 .setFallbackLineSpacing(textView.isFallbackLineSpacing())
248                 .setLineBreakStyle(textView.getLineBreakStyle())
249                 .setLineBreakWordStyle(textView.getLineBreakWordStyle())
250                 .setHighlightTextColor(textView.getHighlightColor())
251                 .setHintTextColor(textView.getCurrentHintTextColor());
252         return builder.build();
253     }
254 
255     @Override
describeContents()256     public int describeContents() {
257         return 0;
258     }
259 
260     @Override
writeToParcel(@onNull Parcel dest, int flags)261     public void writeToParcel(@NonNull Parcel dest, int flags) {
262         dest.writeFloat(mTextSize);
263         mTextLocales.writeToParcel(dest, flags); // NonNull
264         dest.writeBoolean(mAllCaps);
265         dest.writeString8(mSystemFontFamilyName);
266         dest.writeInt(mTextFontWeight);
267         dest.writeInt(mTextStyle);
268         dest.writeFloat(mShadowDx);
269         dest.writeFloat(mShadowDy);
270         dest.writeFloat(mShadowRadius);
271         dest.writeInt(mShadowColor);
272         dest.writeBoolean(mElegantTextHeight);
273         dest.writeBoolean(mFallbackLineSpacing);
274         dest.writeFloat(mLetterSpacing);
275         dest.writeString8(mFontFeatureSettings);
276         dest.writeString8(mFontVariationSettings);
277         dest.writeInt(mLineBreakStyle);
278         dest.writeInt(mLineBreakWordStyle);
279         dest.writeFloat(mTextScaleX);
280         dest.writeInt(mHighlightTextColor);
281         dest.writeInt(mTextColor);
282         dest.writeInt(mHintTextColor);
283         dest.writeInt(mLinkTextColor);
284     }
285 
TextAppearanceInfo(@onNull Parcel in)286     TextAppearanceInfo(@NonNull Parcel in) {
287         mTextSize = in.readFloat();
288         mTextLocales = LocaleList.CREATOR.createFromParcel(in);
289         mAllCaps = in.readBoolean();
290         mSystemFontFamilyName = in.readString8();
291         mTextFontWeight = in.readInt();
292         mTextStyle = in.readInt();
293         mShadowDx = in.readFloat();
294         mShadowDy = in.readFloat();
295         mShadowRadius = in.readFloat();
296         mShadowColor = in.readInt();
297         mElegantTextHeight = in.readBoolean();
298         mFallbackLineSpacing = in.readBoolean();
299         mLetterSpacing = in.readFloat();
300         mFontFeatureSettings = in.readString8();
301         mFontVariationSettings = in.readString8();
302         mLineBreakStyle = in.readInt();
303         mLineBreakWordStyle = in.readInt();
304         mTextScaleX = in.readFloat();
305         mHighlightTextColor = in.readInt();
306         mTextColor = in.readInt();
307         mHintTextColor = in.readInt();
308         mLinkTextColor = in.readInt();
309     }
310 
311     @NonNull
312     public static final Creator<TextAppearanceInfo> CREATOR = new Creator<TextAppearanceInfo>() {
313         @Override
314         public TextAppearanceInfo createFromParcel(@NonNull Parcel in) {
315             return new TextAppearanceInfo(in);
316         }
317 
318         @Override
319         public TextAppearanceInfo[] newArray(int size) {
320             return new TextAppearanceInfo[size];
321         }
322     };
323 
324     /**
325      * Returns the text size (in pixels) for current editor.
326      */
getTextSize()327     public @Px float getTextSize() {
328         return mTextSize;
329     }
330 
331     /**
332      * Returns the {@link LocaleList} of the text.
333      */
334     @NonNull
getTextLocales()335     public LocaleList getTextLocales() {
336         return mTextLocales;
337     }
338 
339     /**
340      * Returns the font family name if the {@link Typeface} of the text is created from a
341      * system font family. Returns null if no {@link Typeface} is specified, or it is not created
342      * from a system font family.
343      *
344      * @see Typeface#getSystemFontFamilyName()
345      */
346     @Nullable
getSystemFontFamilyName()347     public String getSystemFontFamilyName() {
348         return mSystemFontFamilyName;
349     }
350 
351     /**
352      * Returns the weight of the text, or {@code FontStyle#FONT_WEIGHT_UNSPECIFIED}
353      * when no {@link Typeface} is specified.
354      */
355     @IntRange(from = FontStyle.FONT_WEIGHT_UNSPECIFIED, to = FontStyle.FONT_WEIGHT_MAX)
getTextFontWeight()356     public int getTextFontWeight() {
357         return mTextFontWeight;
358     }
359 
360     /**
361      * Returns the style (normal, bold, italic, bold|italic) of the text. Returns
362      * {@link Typeface#NORMAL} when no {@link Typeface} is specified.
363      *
364      * @see Typeface
365      */
getTextStyle()366     public @Typeface.Style int getTextStyle() {
367         return mTextStyle;
368     }
369 
370     /**
371      * Returns whether the transformation method applied to the current editor is set to all caps.
372      *
373      * @see TextView#setAllCaps(boolean)
374      * @see TextView#setTransformationMethod(TransformationMethod)
375      */
isAllCaps()376     public boolean isAllCaps() {
377         return mAllCaps;
378     }
379 
380     /**
381      * Returns the horizontal offset (in pixels) of the text shadow.
382      *
383      * @see Paint#setShadowLayer(float, float, float, int)
384      */
getShadowDx()385     public @Px float getShadowDx() {
386         return mShadowDx;
387     }
388 
389     /**
390      * Returns the vertical offset (in pixels) of the text shadow.
391      *
392      * @see Paint#setShadowLayer(float, float, float, int)
393      */
getShadowDy()394     public @Px float getShadowDy() {
395         return mShadowDy;
396     }
397 
398     /**
399      * Returns the blur radius (in pixels) of the text shadow.
400      *
401      * @see Paint#setShadowLayer(float, float, float, int)
402      */
getShadowRadius()403     public @Px float getShadowRadius() {
404         return mShadowRadius;
405     }
406 
407     /**
408      * Returns the color of the text shadow.
409      *
410      * @see Paint#setShadowLayer(float, float, float, int)
411      */
getShadowColor()412     public @ColorInt int getShadowColor() {
413         return mShadowColor;
414     }
415 
416     /**
417      * Returns {@code true} if the elegant height metrics flag is set. This setting selects font
418      * variants that have not been compacted to fit Latin-based vertical metrics, and also increases
419      * top and bottom bounds to provide more space.
420      *
421      * @see Paint#isElegantTextHeight()
422      */
isElegantTextHeight()423     public boolean isElegantTextHeight() {
424         return mElegantTextHeight;
425     }
426 
427     /**
428      * Returns whether to expand linespacing based on fallback fonts.
429      *
430      * @see TextView#setFallbackLineSpacing(boolean)
431      */
isFallbackLineSpacing()432     public boolean isFallbackLineSpacing() {
433         return mFallbackLineSpacing;
434     }
435 
436     /**
437      * Returns the text letter-spacing, which determines the spacing between characters.
438      * The value is in 'EM' units. Normally, this value is 0.0.
439      */
getLetterSpacing()440     public float getLetterSpacing() {
441         return mLetterSpacing;
442     }
443 
444     /**
445      * Returns the font feature settings. Returns null if not specified.
446      *
447      * @see Paint#getFontFeatureSettings()
448      */
449     @Nullable
getFontFeatureSettings()450     public String getFontFeatureSettings() {
451         return mFontFeatureSettings;
452     }
453 
454     /**
455      * Returns the font variation settings. Returns null if no variation is specified.
456      *
457      * @see Paint#getFontVariationSettings()
458      */
459     @Nullable
getFontVariationSettings()460     public String getFontVariationSettings() {
461         return mFontVariationSettings;
462     }
463 
464     /**
465      * Returns the line-break strategies for text wrapping.
466      *
467      * @see TextView#setLineBreakStyle(int)
468      */
getLineBreakStyle()469     public @LineBreakConfig.LineBreakStyle int getLineBreakStyle() {
470         return mLineBreakStyle;
471     }
472 
473     /**
474      * Returns the line-break word strategies for text wrapping.
475      *
476      * @see TextView#setLineBreakWordStyle(int)
477      */
getLineBreakWordStyle()478     public @LineBreakConfig.LineBreakWordStyle int getLineBreakWordStyle() {
479         return mLineBreakWordStyle;
480     }
481 
482     /**
483      * Returns the extent by which text should be stretched horizontally. Returns 1.0 if not
484      * specified.
485      */
getTextScaleX()486     public float getTextScaleX() {
487         return mTextScaleX;
488     }
489 
490     /**
491      * Returns the color of the text selection highlight.
492      *
493      * @see TextView#getHighlightColor()
494      */
getHighlightTextColor()495     public @ColorInt int getHighlightTextColor() {
496         return mHighlightTextColor;
497     }
498 
499     /**
500      * Returns the current text color of the editor.
501      *
502      * @see TextView#getCurrentTextColor()
503      */
getTextColor()504     public @ColorInt int getTextColor() {
505         return mTextColor;
506     }
507 
508     /**
509      * Returns the current color of the hint text.
510      *
511      * @see TextView#getCurrentHintTextColor()
512      */
getHintTextColor()513     public @ColorInt int getHintTextColor() {
514         return mHintTextColor;
515     }
516 
517     /**
518      * Returns the text color used to paint the links in the editor.
519      *
520      * @see TextView#getLinkTextColors()
521      */
getLinkTextColor()522     public @ColorInt int getLinkTextColor() {
523         return mLinkTextColor;
524     }
525 
526 
527     @Override
equals(Object o)528     public boolean equals(Object o) {
529         if (this == o) return true;
530         if (!(o instanceof TextAppearanceInfo)) return false;
531         TextAppearanceInfo that = (TextAppearanceInfo) o;
532         return Float.compare(that.mTextSize, mTextSize) == 0
533                 && mTextFontWeight == that.mTextFontWeight && mTextStyle == that.mTextStyle
534                 && mAllCaps == that.mAllCaps && Float.compare(that.mShadowDx, mShadowDx) == 0
535                 && Float.compare(that.mShadowDy, mShadowDy) == 0 && Float.compare(
536                 that.mShadowRadius, mShadowRadius) == 0 && that.mShadowColor == mShadowColor
537                 && mElegantTextHeight == that.mElegantTextHeight
538                 && mFallbackLineSpacing == that.mFallbackLineSpacing && Float.compare(
539                 that.mLetterSpacing, mLetterSpacing) == 0 && mLineBreakStyle == that.mLineBreakStyle
540                 && mLineBreakWordStyle == that.mLineBreakWordStyle
541                 && mHighlightTextColor == that.mHighlightTextColor
542                 && mTextColor == that.mTextColor
543                 && mLinkTextColor == that.mLinkTextColor
544                 && mHintTextColor == that.mHintTextColor
545                 && Objects.equals(mTextLocales, that.mTextLocales)
546                 && Objects.equals(mSystemFontFamilyName, that.mSystemFontFamilyName)
547                 && Objects.equals(mFontFeatureSettings, that.mFontFeatureSettings)
548                 && Objects.equals(mFontVariationSettings, that.mFontVariationSettings)
549                 && Float.compare(that.mTextScaleX, mTextScaleX) == 0;
550     }
551 
552     @Override
hashCode()553     public int hashCode() {
554         return Objects.hash(mTextSize, mTextLocales, mSystemFontFamilyName, mTextFontWeight,
555                 mTextStyle, mAllCaps, mShadowDx, mShadowDy, mShadowRadius, mShadowColor,
556                 mElegantTextHeight, mFallbackLineSpacing, mLetterSpacing, mFontFeatureSettings,
557                 mFontVariationSettings, mLineBreakStyle, mLineBreakWordStyle, mTextScaleX,
558                 mHighlightTextColor, mTextColor, mHintTextColor, mLinkTextColor);
559     }
560 
561     @Override
toString()562     public String toString() {
563         return "TextAppearanceInfo{"
564                 + "mTextSize=" + mTextSize
565                 + ", mTextLocales=" + mTextLocales
566                 + ", mSystemFontFamilyName='" + mSystemFontFamilyName + '\''
567                 + ", mTextFontWeight=" + mTextFontWeight
568                 + ", mTextStyle=" + mTextStyle
569                 + ", mAllCaps=" + mAllCaps
570                 + ", mShadowDx=" + mShadowDx
571                 + ", mShadowDy=" + mShadowDy
572                 + ", mShadowRadius=" + mShadowRadius
573                 + ", mShadowColor=" + mShadowColor
574                 + ", mElegantTextHeight=" + mElegantTextHeight
575                 + ", mFallbackLineSpacing=" + mFallbackLineSpacing
576                 + ", mLetterSpacing=" + mLetterSpacing
577                 + ", mFontFeatureSettings='" + mFontFeatureSettings + '\''
578                 + ", mFontVariationSettings='" + mFontVariationSettings + '\''
579                 + ", mLineBreakStyle=" + mLineBreakStyle
580                 + ", mLineBreakWordStyle=" + mLineBreakWordStyle
581                 + ", mTextScaleX=" + mTextScaleX
582                 + ", mHighlightTextColor=" + mHighlightTextColor
583                 + ", mTextColor=" + mTextColor
584                 + ", mHintTextColor=" + mHintTextColor
585                 + ", mLinkTextColor=" + mLinkTextColor
586                 + '}';
587     }
588 
589     /**
590      * Builder for {@link TextAppearanceInfo}.
591      */
592     public static final class Builder {
593         private @Px float mTextSize = -1;
594         private @NonNull LocaleList mTextLocales = LocaleList.getAdjustedDefault();
595         @Nullable private String mSystemFontFamilyName = null;
596         @IntRange(from = FontStyle.FONT_WEIGHT_UNSPECIFIED, to = FontStyle.FONT_WEIGHT_MAX)
597         private int mTextFontWeight = FontStyle.FONT_WEIGHT_UNSPECIFIED;
598         private @Typeface.Style int mTextStyle = NORMAL;
599         private boolean mAllCaps = false;
600         private @Px float mShadowDx = 0;
601         private @Px float mShadowDy = 0;
602         private @Px float mShadowRadius = 0;
603         private @ColorInt int mShadowColor = 0;
604         private boolean mElegantTextHeight = false;
605         private boolean mFallbackLineSpacing = false;
606         private float mLetterSpacing = 0;
607         @Nullable private String mFontFeatureSettings = null;
608         @Nullable private String mFontVariationSettings = null;
609         @LineBreakConfig.LineBreakStyle
610         private int mLineBreakStyle = LineBreakConfig.LINE_BREAK_STYLE_NONE;
611         @LineBreakConfig.LineBreakWordStyle
612         private int mLineBreakWordStyle = LineBreakConfig.LINE_BREAK_WORD_STYLE_NONE;
613         private float mTextScaleX = 1;
614         private @ColorInt int mHighlightTextColor = 0;
615         private @ColorInt int mTextColor = 0;
616         private @ColorInt int mHintTextColor = 0;
617         private @ColorInt int mLinkTextColor = 0;
618 
619         /**
620          * Set the text size (in pixels) obtained from the current editor.
621          */
622         @NonNull
setTextSize(@x float textSize)623         public Builder setTextSize(@Px float textSize) {
624             mTextSize = textSize;
625             return this;
626         }
627 
628         /**
629          * Set the {@link LocaleList} of the text.
630          */
631         @NonNull
setTextLocales(@onNull LocaleList textLocales)632         public Builder setTextLocales(@NonNull LocaleList textLocales) {
633             mTextLocales = textLocales;
634             return this;
635         }
636 
637         /**
638          * Set the system font family name if the {@link Typeface} of the text is created from a
639          * system font family.
640          *
641          * @see Typeface#getSystemFontFamilyName()
642          */
643         @NonNull
setSystemFontFamilyName(@ullable String systemFontFamilyName)644         public Builder setSystemFontFamilyName(@Nullable String systemFontFamilyName) {
645             mSystemFontFamilyName = systemFontFamilyName;
646             return this;
647         }
648 
649         /**
650          * Set the weight of the text.
651          */
652         @NonNull
setTextFontWeight( @ntRangefrom = FontStyle.FONT_WEIGHT_UNSPECIFIED, to = FontStyle.FONT_WEIGHT_MAX) int textFontWeight)653         public Builder setTextFontWeight(
654                 @IntRange(from = FontStyle.FONT_WEIGHT_UNSPECIFIED,
655                         to = FontStyle.FONT_WEIGHT_MAX) int textFontWeight) {
656             mTextFontWeight = textFontWeight;
657             return this;
658         }
659 
660         /**
661          * Set the style (normal, bold, italic, bold|italic) of the text.
662          *
663          * @see Typeface
664          */
665         @NonNull
setTextStyle(@ypeface.Style int textStyle)666         public Builder setTextStyle(@Typeface.Style int textStyle) {
667             mTextStyle = textStyle;
668             return this;
669         }
670 
671         /**
672          * Set whether the transformation method applied to the current editor  is set to all caps.
673          *
674          * @see TextView#setAllCaps(boolean)
675          * @see TextView#setTransformationMethod(TransformationMethod)
676          */
677         @NonNull
setAllCaps(boolean allCaps)678         public Builder setAllCaps(boolean allCaps) {
679             mAllCaps = allCaps;
680             return this;
681         }
682 
683         /**
684          * Set the horizontal offset (in pixels) of the text shadow.
685          *
686          * @see Paint#setShadowLayer(float, float, float, int)
687          */
688         @NonNull
setShadowDx(@x float shadowDx)689         public Builder setShadowDx(@Px float shadowDx) {
690             mShadowDx = shadowDx;
691             return this;
692         }
693 
694         /**
695          * Set the vertical offset (in pixels) of the text shadow.
696          *
697          * @see Paint#setShadowLayer(float, float, float, int)
698          */
699         @NonNull
setShadowDy(@x float shadowDy)700         public Builder setShadowDy(@Px float shadowDy) {
701             mShadowDy = shadowDy;
702             return this;
703         }
704 
705         /**
706          * Set the blur radius (in pixels) of the text shadow.
707          *
708          * @see Paint#setShadowLayer(float, float, float, int)
709          */
710         @NonNull
setShadowRadius(@x float shadowRadius)711         public Builder setShadowRadius(@Px float shadowRadius) {
712             mShadowRadius = shadowRadius;
713             return this;
714         }
715 
716         /**
717          * Set the color of the text shadow.
718          *
719          * @see Paint#setShadowLayer(float, float, float, int)
720          */
721         @NonNull
setShadowColor(@olorInt int shadowColor)722         public Builder setShadowColor(@ColorInt int shadowColor) {
723             mShadowColor = shadowColor;
724             return this;
725         }
726 
727         /**
728          * Set the elegant height metrics flag. This setting selects font variants that
729          * have not been compacted to fit Latin-based vertical metrics, and also increases
730          * top and bottom bounds to provide more space.
731          *
732          * @see Paint#isElegantTextHeight()
733          */
734         @NonNull
setElegantTextHeight(boolean elegantTextHeight)735         public Builder setElegantTextHeight(boolean elegantTextHeight) {
736             mElegantTextHeight = elegantTextHeight;
737             return this;
738         }
739 
740         /**
741          * Set whether to expand linespacing based on fallback fonts.
742          *
743          * @see TextView#setFallbackLineSpacing(boolean)
744          */
745         @NonNull
setFallbackLineSpacing(boolean fallbackLineSpacing)746         public Builder setFallbackLineSpacing(boolean fallbackLineSpacing) {
747             mFallbackLineSpacing = fallbackLineSpacing;
748             return this;
749         }
750 
751         /**
752          * Set the text letter-spacing, which determines the spacing between characters.
753          * The value is in 'EM' units. Normally, this value is 0.0.
754          */
755         @NonNull
setLetterSpacing(float letterSpacing)756         public Builder setLetterSpacing(float letterSpacing) {
757             mLetterSpacing = letterSpacing;
758             return this;
759         }
760 
761         /**
762          * Set the font feature settings.
763          *
764          * @see Paint#getFontFeatureSettings()
765          */
766         @NonNull
setFontFeatureSettings(@ullable String fontFeatureSettings)767         public Builder setFontFeatureSettings(@Nullable String fontFeatureSettings) {
768             mFontFeatureSettings = fontFeatureSettings;
769             return this;
770         }
771 
772         /**
773          * Set the font variation settings. Returns null if no variation is specified.
774          *
775          * @see Paint#getFontVariationSettings()
776          */
777         @NonNull
setFontVariationSettings(@ullable String fontVariationSettings)778         public Builder setFontVariationSettings(@Nullable String fontVariationSettings) {
779             mFontVariationSettings = fontVariationSettings;
780             return this;
781         }
782 
783         /**
784          * Set the line-break strategies for text wrapping.
785          *
786          * @see TextView#setLineBreakStyle(int)
787          */
788         @NonNull
setLineBreakStyle(@ineBreakConfig.LineBreakStyle int lineBreakStyle)789         public Builder setLineBreakStyle(@LineBreakConfig.LineBreakStyle int lineBreakStyle) {
790             mLineBreakStyle = lineBreakStyle;
791             return this;
792         }
793 
794         /**
795          * Set the line-break word strategies for text wrapping.
796          *
797          * @see TextView#setLineBreakWordStyle(int)
798          */
799         @NonNull
setLineBreakWordStyle( @ineBreakConfig.LineBreakWordStyle int lineBreakWordStyle)800         public Builder setLineBreakWordStyle(
801                 @LineBreakConfig.LineBreakWordStyle int lineBreakWordStyle) {
802             mLineBreakWordStyle = lineBreakWordStyle;
803             return this;
804         }
805 
806         /**
807          * Set the extent by which text should be stretched horizontally.
808          */
809         @NonNull
setTextScaleX(float textScaleX)810         public Builder setTextScaleX(float textScaleX) {
811             mTextScaleX = textScaleX;
812             return this;
813         }
814 
815         /**
816          * Set the color of the text selection highlight.
817          *
818          * @see TextView#getHighlightColor()
819          */
820         @NonNull
setHighlightTextColor(@olorInt int highlightTextColor)821         public Builder setHighlightTextColor(@ColorInt int highlightTextColor) {
822             mHighlightTextColor = highlightTextColor;
823             return this;
824         }
825 
826         /**
827          * Set the current text color of the editor.
828          *
829          * @see TextView#getCurrentTextColor()
830          */
831         @NonNull
setTextColor(@olorInt int textColor)832         public Builder setTextColor(@ColorInt int textColor) {
833             mTextColor = textColor;
834             return this;
835         }
836 
837         /**
838          * Set the current color of the hint text.
839          *
840          * @see TextView#getCurrentHintTextColor()
841          */
842         @NonNull
setHintTextColor(@olorInt int hintTextColor)843         public Builder setHintTextColor(@ColorInt int hintTextColor) {
844             mHintTextColor = hintTextColor;
845             return this;
846         }
847 
848         /**
849          * Set the text color used to paint the links in the editor.
850          *
851          * @see TextView#getLinkTextColors()
852          */
853         @NonNull
setLinkTextColor(@olorInt int linkTextColor)854         public Builder setLinkTextColor(@ColorInt int linkTextColor) {
855             mLinkTextColor = linkTextColor;
856             return this;
857         }
858 
859         /**
860          * Returns {@link TextAppearanceInfo} using parameters in this
861          * {@link TextAppearanceInfo.Builder}.
862          */
863         @NonNull
build()864         public TextAppearanceInfo build() {
865             return new TextAppearanceInfo(this);
866         }
867     }
868 }
869