• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2017 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.text;
18 
19 import static java.lang.annotation.RetentionPolicy.SOURCE;
20 
21 import android.annotation.CurrentTimeMillisLong;
22 import android.annotation.IntDef;
23 import android.annotation.IntRange;
24 import android.annotation.NonNull;
25 import android.annotation.Nullable;
26 import android.annotation.SystemApi;
27 import android.annotation.TestApi;
28 import android.compat.annotation.UnsupportedAppUsage;
29 import android.graphics.fonts.FontStyle;
30 import android.graphics.fonts.FontVariationAxis;
31 import android.os.Build;
32 import android.os.LocaleList;
33 import android.os.Parcel;
34 import android.os.Parcelable;
35 
36 import java.io.File;
37 import java.lang.annotation.Retention;
38 import java.util.ArrayList;
39 import java.util.List;
40 import java.util.Objects;
41 
42 
43 /**
44  * Font configuration descriptions for System fonts.
45  *
46  * FontConfig represents the configuration for the fonts installed on the system. It is made of list
47  * of font families and aliases.
48  *
49  * @see FontFamily
50  * @see Alias
51  * @hide
52  */
53 @SystemApi
54 @TestApi
55 public final class FontConfig implements Parcelable {
56     private final @NonNull List<FontFamily> mFamilies;
57     private final @NonNull List<Alias> mAliases;
58     private final long mLastModifiedTimeMillis;
59     private final int mConfigVersion;
60 
61     /**
62      * Construct a FontConfig instance.
63      *
64      * @param families a list of font families.
65      * @param aliases a list of aliases.
66      *
67      * @hide Only system server can create this instance and passed via IPC.
68      */
FontConfig(@onNull List<FontFamily> families, @NonNull List<Alias> aliases, long lastModifiedTimeMillis, @IntRange(from = 0) int configVersion)69     public FontConfig(@NonNull List<FontFamily> families, @NonNull List<Alias> aliases,
70             long lastModifiedTimeMillis, @IntRange(from = 0) int configVersion) {
71         mFamilies = families;
72         mAliases = aliases;
73         mLastModifiedTimeMillis = lastModifiedTimeMillis;
74         mConfigVersion = configVersion;
75     }
76 
77     /**
78      * Returns the ordered list of font families available in the system.
79      *
80      * @return a list of font families.
81      * @see FontFamily
82      */
getFontFamilies()83     public @NonNull List<FontFamily> getFontFamilies() {
84         return mFamilies;
85     }
86 
87     /**
88      * Returns the list of aliases for mapping font families with other names.
89      *
90      * @return a list of font families.
91      * @see Alias
92      */
getAliases()93     public @NonNull List<Alias> getAliases() {
94         return mAliases;
95     }
96 
97     /**
98      * Returns the last modified time in milliseconds.
99      *
100      * This is a value of {@link System#currentTimeMillis()} when the system font configuration was
101      * modified last time.
102      *
103      * If there is no update, this return 0.
104      */
getLastModifiedTimeMillis()105     public @CurrentTimeMillisLong long getLastModifiedTimeMillis() {
106         return mLastModifiedTimeMillis;
107     }
108 
109     /**
110      * Returns the monotonically increasing config version value.
111      *
112      * The config version is reset to 0 when the system is restarted.
113      */
getConfigVersion()114     public @IntRange(from = 0) int getConfigVersion() {
115         return mConfigVersion;
116     }
117 
118     /**
119      * Returns the ordered list of families included in the system fonts.
120      * @deprecated Use getFontFamilies instead.
121      * @hide
122      */
123     @Deprecated
124     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
getFamilies()125     public @NonNull FontFamily[] getFamilies() {
126         return mFamilies.toArray(new FontFamily[0]);
127     }
128 
129     @Override
describeContents()130     public int describeContents() {
131         return 0;
132     }
133 
134     @Override
writeToParcel(@onNull Parcel dest, int flags)135     public void writeToParcel(@NonNull Parcel dest, int flags) {
136         dest.writeParcelableList(mFamilies, flags);
137         dest.writeParcelableList(mAliases, flags);
138         dest.writeLong(mLastModifiedTimeMillis);
139         dest.writeInt(mConfigVersion);
140     }
141 
142     public static final @NonNull Creator<FontConfig> CREATOR = new Creator<FontConfig>() {
143         @Override
144         public FontConfig createFromParcel(Parcel source) {
145             List<FontFamily> families = source.readParcelableList(new ArrayList<>(),
146                     FontFamily.class.getClassLoader());
147             List<Alias> aliases = source.readParcelableList(new ArrayList<>(),
148                     Alias.class.getClassLoader());
149             long lastModifiedDate = source.readLong();
150             int configVersion = source.readInt();
151             return new FontConfig(families, aliases, lastModifiedDate, configVersion);
152         }
153 
154         @Override
155         public FontConfig[] newArray(int size) {
156             return new FontConfig[size];
157         }
158     };
159 
160     @Override
equals(Object o)161     public boolean equals(Object o) {
162         if (this == o) return true;
163         if (o == null || getClass() != o.getClass()) return false;
164         FontConfig that = (FontConfig) o;
165         return mLastModifiedTimeMillis == that.mLastModifiedTimeMillis
166                 && mConfigVersion == that.mConfigVersion
167                 && Objects.equals(mFamilies, that.mFamilies)
168                 && Objects.equals(mAliases, that.mAliases);
169     }
170 
171     @Override
hashCode()172     public int hashCode() {
173         return Objects.hash(mFamilies, mAliases, mLastModifiedTimeMillis, mConfigVersion);
174     }
175 
176     @Override
toString()177     public String toString() {
178         return "FontConfig{"
179                 + "mFamilies=" + mFamilies
180                 + ", mAliases=" + mAliases
181                 + ", mLastModifiedTimeMillis=" + mLastModifiedTimeMillis
182                 + ", mConfigVersion=" + mConfigVersion
183                 + '}';
184     }
185 
186     /**
187      * Represents single font entry in system font configuration.
188      *
189      * A font is the most primitive unit of drawing character shapes. A font in system configuration
190      * is always referring a single OpenType compliant regular file in the file system.
191      *
192      * @see android.graphics.fonts.Font
193      */
194     public static final class Font implements Parcelable {
195         private final @NonNull File mFile;
196         private final @Nullable File mOriginalFile;
197         private final @NonNull String mPostScriptName;
198         private final @NonNull FontStyle mStyle;
199         private final @IntRange(from = 0) int mIndex;
200         private final @NonNull String mFontVariationSettings;
201         private final @Nullable String mFontFamilyName;
202 
203         /**
204          * Construct a Font instance.
205          *
206          * @hide Only system server can create this instance and passed via IPC.
207          */
Font(@onNull File file, @Nullable File originalFile, @NonNull String postScriptName, @NonNull FontStyle style, @IntRange(from = 0) int index, @NonNull String fontVariationSettings, @Nullable String fontFamilyName)208         public Font(@NonNull File file, @Nullable File originalFile, @NonNull String postScriptName,
209                 @NonNull FontStyle style, @IntRange(from = 0) int index,
210                 @NonNull String fontVariationSettings, @Nullable String fontFamilyName) {
211             mFile = file;
212             mOriginalFile = originalFile;
213             mPostScriptName = postScriptName;
214             mStyle = style;
215             mIndex = index;
216             mFontVariationSettings = fontVariationSettings;
217             mFontFamilyName = fontFamilyName;
218         }
219 
220         @Override
describeContents()221         public int describeContents() {
222             return 0;
223         }
224 
225         @Override
writeToParcel(@onNull Parcel dest, int flags)226         public void writeToParcel(@NonNull Parcel dest, int flags) {
227             dest.writeString8(mFile.getAbsolutePath());
228             dest.writeString8(mOriginalFile == null ? null : mOriginalFile.getAbsolutePath());
229             dest.writeString8(mPostScriptName);
230             dest.writeInt(mStyle.getWeight());
231             dest.writeInt(mStyle.getSlant());
232             dest.writeInt(mIndex);
233             dest.writeString8(mFontVariationSettings);
234             dest.writeString8(mFontFamilyName);
235         }
236 
237         public static final @NonNull Creator<Font> CREATOR = new Creator<Font>() {
238 
239             @Override
240             public Font createFromParcel(Parcel source) {
241                 File path = new File(source.readString8());
242                 String originalPathStr = source.readString8();
243                 File originalPath = originalPathStr == null ? null : new File(originalPathStr);
244                 String postScriptName = source.readString8();
245                 int weight = source.readInt();
246                 int slant = source.readInt();
247                 int index = source.readInt();
248                 String varSettings = source.readString8();
249                 String fallback = source.readString8();
250 
251                 return new Font(path, originalPath, postScriptName, new FontStyle(weight, slant),
252                         index, varSettings, fallback);
253             }
254 
255             @Override
256             public Font[] newArray(int size) {
257                 return new Font[size];
258             }
259         };
260 
261         /**
262          * Returns the font file.
263          */
getFile()264         public @NonNull File getFile() {
265             return mFile;
266         }
267 
268         /**
269          * Returns the original font file in the system directory.
270          *
271          * If the font file is not updated, returns null.
272          *
273          * @return returns the original font file in the system if the font file is updated. Returns
274          *         null if the font file is not updated.
275          * @hide
276          */
getOriginalFile()277         public @Nullable File getOriginalFile() {
278             return mOriginalFile;
279         }
280 
281         /**
282          * Returns the font style.
283          */
getStyle()284         public @NonNull FontStyle getStyle() {
285             return mStyle;
286         }
287 
288 
289         /**
290          * Return a font variation settings.
291          */
getFontVariationSettings()292         public @NonNull String getFontVariationSettings() {
293             return mFontVariationSettings;
294         }
295 
296         /**
297          * A {@link Font} can be configured to be in the {@code Fallback List} for a
298          * {@link FontFamily}.
299          *
300          * For example a serif Hebrew [Font] can be defined in the {@code Fallback List} for
301          * {@code "serif"} {@link FontFamily}.
302          *
303          * If the return value is not {@code null}, then the font will be used in the
304          * {@code Fallback List} of that {@link FontFamily}.
305          *
306          * If the return value is {@code null}, then the font will be used in {@code Fallback List}
307          * of all {@link FontFamily}s.
308          */
getFontFamilyName()309         public @Nullable String getFontFamilyName() {
310             return mFontFamilyName;
311         }
312 
313         /**
314          * Returns the index to be used to access this font when accessing a TTC file.
315          */
getTtcIndex()316         public int getTtcIndex() {
317             return mIndex;
318         }
319 
320         /**
321          * Returns the PostScript name of this font.
322          */
getPostScriptName()323         public @NonNull String getPostScriptName() {
324             return mPostScriptName;
325         }
326 
327         /**
328          * Returns the list of axes associated to this font.
329          * @deprecated Use getFontVariationSettings
330          * @hide
331          */
332         @Deprecated
333         @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
getAxes()334         public @NonNull FontVariationAxis[] getAxes() {
335             return FontVariationAxis.fromFontVariationSettings(mFontVariationSettings);
336         }
337 
338         /**
339          * Returns the weight value for this font.
340          * @deprecated Use getStyle instead.
341          * @hide
342          */
343         @Deprecated
344         @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
getWeight()345         public int getWeight() {
346             return getStyle().getWeight();
347         }
348 
349         /**
350          * Returns whether this font is italic.
351          * @deprecated Use getStyle instead.
352          * @hide
353          */
354         @Deprecated
355         @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
isItalic()356         public boolean isItalic() {
357             return getStyle().getSlant() == FontStyle.FONT_SLANT_ITALIC;
358         }
359 
360         @Override
equals(Object o)361         public boolean equals(Object o) {
362             if (this == o) return true;
363             if (o == null || getClass() != o.getClass()) return false;
364             Font font = (Font) o;
365             return mIndex == font.mIndex
366                     && Objects.equals(mFile, font.mFile)
367                     && Objects.equals(mOriginalFile, font.mOriginalFile)
368                     && Objects.equals(mStyle, font.mStyle)
369                     && Objects.equals(mFontVariationSettings, font.mFontVariationSettings)
370                     && Objects.equals(mFontFamilyName, font.mFontFamilyName);
371         }
372 
373         @Override
hashCode()374         public int hashCode() {
375             return Objects.hash(mFile, mOriginalFile, mStyle, mIndex, mFontVariationSettings,
376                     mFontFamilyName);
377         }
378 
379         @Override
toString()380         public String toString() {
381             return "Font{"
382                     + "mFile=" + mFile
383                     + ", mOriginalFile=" + mOriginalFile
384                     + ", mStyle=" + mStyle
385                     + ", mIndex=" + mIndex
386                     + ", mFontVariationSettings='" + mFontVariationSettings + '\''
387                     + ", mFontFamilyName='" + mFontFamilyName + '\''
388                     + '}';
389         }
390     }
391 
392     /**
393      * Alias provides an alternative name for an existing font family.
394      *
395      * In the system font configuration, a font family can be an alias of another font family with
396      * different font weight. For example, "sans-serif-medium" can be a medium weight of
397      * "sans-serif" font family. In this example, {@link #getName()} returns "sans-serif-medium" and
398      * {@link #getOriginal()} return "sans-serif". The font family that doesn't have name can not be
399      * an original of the alias.
400      */
401     public static final class Alias implements Parcelable {
402         private final @NonNull String mName;
403         private final @NonNull String mOriginal;
404         private final @IntRange(from = 0, to = 1000) int mWeight;
405 
406         /**
407          * Construct an alias instance.
408          *
409          * @param name alias for the font family.
410          * @param original original font family name.
411          * @param weight font weight of the original font family.
412          * @hide Only system server can create this instance and passed via IPC.
413          */
Alias(@onNull String name, @NonNull String original, @IntRange(from = 0, to = 1000) int weight)414         public Alias(@NonNull String name, @NonNull String original,
415                 @IntRange(from = 0, to = 1000) int weight) {
416             mName = name;
417             mOriginal = original;
418             mWeight = weight;
419         }
420 
421         /**
422          * Alias for the font family
423          */
getName()424         public @NonNull String getName() {
425             return mName;
426         }
427 
428         /**
429          * The name of the original font family.
430          */
getOriginal()431         public @NonNull String getOriginal() {
432             return mOriginal;
433         }
434 
435         /**
436          * A font weight of the referring font family.
437          *
438          * @return a font weight of the referring font family.
439          */
getWeight()440         public @IntRange(from = 0, to = 1000) int getWeight() {
441             return mWeight;
442         }
443 
444         @Override
describeContents()445         public int describeContents() {
446             return 0;
447         }
448 
449         @Override
writeToParcel(@onNull Parcel dest, int flags)450         public void writeToParcel(@NonNull Parcel dest, int flags) {
451             dest.writeString8(mName);
452             dest.writeString8(mOriginal);
453             dest.writeInt(mWeight);
454         }
455 
456         public static final @NonNull Creator<Alias> CREATOR = new Creator<Alias>() {
457 
458             @Override
459             public Alias createFromParcel(Parcel source) {
460                 String alias = source.readString8();
461                 String referName = source.readString8();
462                 int weight = source.readInt();
463                 return new Alias(alias, referName, weight);
464             }
465 
466             @Override
467             public Alias[] newArray(int size) {
468                 return new Alias[size];
469             }
470         };
471 
472         @Override
equals(Object o)473         public boolean equals(Object o) {
474             if (this == o) return true;
475             if (o == null || getClass() != o.getClass()) return false;
476             Alias alias = (Alias) o;
477             return mWeight == alias.mWeight
478                     && Objects.equals(mName, alias.mName)
479                     && Objects.equals(mOriginal, alias.mOriginal);
480         }
481 
482         @Override
hashCode()483         public int hashCode() {
484             return Objects.hash(mName, mOriginal, mWeight);
485         }
486 
487         @Override
toString()488         public String toString() {
489             return "Alias{"
490                     + "mName='" + mName + '\''
491                     + ", mOriginal='" + mOriginal + '\''
492                     + ", mWeight=" + mWeight
493                     + '}';
494         }
495     }
496 
497     /**
498      * Represents a font family in the system font configuration.
499      *
500      * A {@link FontFamily} is a list of {@link Font}s for drawing text in various styles such as
501      * weight, slant.
502      *
503      * For example, a {@link FontFamily} can include the regular and bold styles of a {@link Font}.
504      *
505      * @see android.graphics.fonts.FontFamily
506      */
507     public static final class FontFamily implements Parcelable {
508         private final @NonNull List<Font> mFonts;
509         private final @Nullable String mName;
510         private final @NonNull LocaleList mLocaleList;
511         private final @Variant int mVariant;
512 
513         /** @hide */
514         @Retention(SOURCE)
515         @IntDef(prefix = { "VARIANT_" }, value = {
516                 VARIANT_DEFAULT,
517                 VARIANT_COMPACT,
518                 VARIANT_ELEGANT
519         })
520         public @interface Variant {}
521 
522         /**
523          * Value for font variant.
524          *
525          * Indicates the font has no variant attribute.
526          */
527         public static final int VARIANT_DEFAULT = 0;
528 
529         /**
530          * Value for font variant.
531          *
532          * Indicates the font is for compact variant.
533          * @see android.graphics.Paint#setElegantTextHeight
534          */
535         public static final int VARIANT_COMPACT = 1;
536 
537         /**
538          * Value for font variant.
539          *
540          * Indicates the font is for elegant variant.
541          * @see android.graphics.Paint#setElegantTextHeight
542          */
543         public static final int VARIANT_ELEGANT = 2;
544 
545         /**
546          * Construct a family instance.
547          *
548          * @hide Only system server can create this instance and passed via IPC.
549          */
FontFamily(@onNull List<Font> fonts, @Nullable String name, @NonNull LocaleList localeList, @Variant int variant)550         public FontFamily(@NonNull List<Font> fonts, @Nullable String name,
551                 @NonNull LocaleList localeList, @Variant int variant) {
552             mFonts = fonts;
553             mName = name;
554             mLocaleList = localeList;
555             mVariant = variant;
556         }
557 
558         /**
559          * Returns the list of {@link Font}s in this {@link FontFamily}.
560          *
561          * @return a list of font files.
562          */
getFontList()563         public @NonNull List<Font> getFontList() {
564             return mFonts;
565         }
566 
567         /**
568          * Returns the name of the {@link FontFamily}.
569          *
570          * When the name of a {@link FontFamily} is not null, this name is used to create a new
571          * {@code Fallback List}, and that {@code Fallback List}. Fallback List is the
572          * main building block for a {@link android.graphics.Typeface}.
573          *
574          * For example, if the {@link FontFamily} has the name "serif", then the system will create
575          * a “serif” {@code Fallback List} and it can be used by creating a Typeface via
576          * {@code Typeface.create("serif", Typeface.NORMAL);}
577          *
578          * When the name of a {@link FontFamily} is null, it will be appended to all of the
579          * {@code Fallback List}s.
580          */
getName()581         public @Nullable String getName() {
582             return mName;
583         }
584 
585         /**
586          * Returns the locale list if available.
587          *
588          * The locale list will be used for deciding which font family should be used in fallback
589          * list.
590          */
getLocaleList()591         public @NonNull LocaleList getLocaleList() {
592             return mLocaleList;
593         }
594 
595         /**
596          * Returns the text height variant.
597          */
getVariant()598         public @Variant int getVariant() {
599             return mVariant;
600         }
601 
602         @Override
describeContents()603         public int describeContents() {
604             return 0;
605         }
606 
607         @Override
writeToParcel(@onNull Parcel dest, int flags)608         public void writeToParcel(@NonNull Parcel dest, int flags) {
609             dest.writeParcelableList(mFonts, flags);
610             dest.writeString8(mName);
611             dest.writeString8(mLocaleList.toLanguageTags());
612             dest.writeInt(mVariant);
613         }
614 
615         public static final @NonNull Creator<FontFamily> CREATOR = new Creator<FontFamily>() {
616 
617             @Override
618             public FontFamily createFromParcel(Parcel source) {
619                 List<Font> fonts = source.readParcelableList(
620                         new ArrayList<>(), Font.class.getClassLoader());
621                 String name = source.readString8();
622                 String langTags = source.readString8();
623                 int variant = source.readInt();
624 
625                 return new FontFamily(fonts, name, LocaleList.forLanguageTags(langTags), variant);
626             }
627 
628             @Override
629             public FontFamily[] newArray(int size) {
630                 return new FontFamily[size];
631             }
632         };
633 
634         /**
635          * Returns the list of fonts included in this family.
636          * @deprecated Use getFontList instead
637          * @hide
638          */
639         @Deprecated
640         @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
getFonts()641         public @Nullable Font[] getFonts() {
642             return mFonts.toArray(new Font[0]);
643         }
644 
645         /**
646          * Returns the comma separated BCP47 compliant languages for this family. May be null.
647          * @deprecated Use getLocaleList instead
648          * @hide
649          */
650         @Deprecated
getLanguages()651         public @NonNull String getLanguages() {
652             return mLocaleList.toLanguageTags();
653         }
654 
655         @Override
equals(Object o)656         public boolean equals(Object o) {
657             if (this == o) return true;
658             if (o == null || getClass() != o.getClass()) return false;
659             FontFamily that = (FontFamily) o;
660             return mVariant == that.mVariant
661                     && Objects.equals(mFonts, that.mFonts)
662                     && Objects.equals(mName, that.mName)
663                     && Objects.equals(mLocaleList, that.mLocaleList);
664         }
665 
666         @Override
hashCode()667         public int hashCode() {
668             return Objects.hash(mFonts, mName, mLocaleList, mVariant);
669         }
670 
671         @Override
toString()672         public String toString() {
673             return "FontFamily{"
674                     + "mFonts=" + mFonts
675                     + ", mName='" + mName + '\''
676                     + ", mLocaleList=" + mLocaleList
677                     + ", mVariant=" + mVariant
678                     + '}';
679         }
680     }
681 }
682