1 | import { Font as FontBase, parseFontFamily, genericFontFamilies, FontWeight, FontVariationSettings } from './font-common';
|
2 | import { Trace } from '../../trace';
|
3 | import { SDK_VERSION } from '../../utils/constants';
|
4 | import * as fs from '../../file-system';
|
5 | import { ad } from '../../utils';
|
6 | export * from './font-common';
|
7 | const FONTS_BASE_PATH = '/fonts/';
|
8 | const typefaceCache = new Map();
|
9 | let appAssets;
|
10 | export class Font extends FontBase {
|
11 | withFontFamily(family) {
|
12 | return new Font(family, this.fontSize, this.fontStyle, this.fontWeight, 1, this.fontVariationSettings);
|
13 | }
|
14 | withFontStyle(style) {
|
15 | return new Font(this.fontFamily, this.fontSize, style, this.fontWeight, 1, this.fontVariationSettings);
|
16 | }
|
17 | withFontWeight(weight) {
|
18 | return new Font(this.fontFamily, this.fontSize, this.fontStyle, weight, 1, this.fontVariationSettings);
|
19 | }
|
20 | withFontSize(size) {
|
21 | return new Font(this.fontFamily, size, this.fontStyle, this.fontWeight, 1, this.fontVariationSettings);
|
22 | }
|
23 | withFontScale(scale) {
|
24 | return new Font(this.fontFamily, this.fontSize, this.fontStyle, this.fontWeight, 1, this.fontVariationSettings);
|
25 | }
|
26 | withFontVariationSettings(variationSettings) {
|
27 | return new Font(this.fontFamily, this.fontSize, this.fontStyle, this.fontWeight, 1, variationSettings);
|
28 | }
|
29 | getAndroidTypeface() {
|
30 | if (!this._typeface) {
|
31 | this._typeface = createTypeface(this);
|
32 | }
|
33 | return this._typeface;
|
34 | }
|
35 | getUIFont(defaultFont) {
|
36 | return undefined;
|
37 | }
|
38 | }
|
39 | Font.default = new Font(undefined, undefined);
|
40 | function computeFontCacheKey(fontFamily, font) {
|
41 | const sep = ':';
|
42 | return [fontFamily, String(FontVariationSettings.toString(font.fontVariationSettings)).replace(/'/g, '').replace(/[\s,]/g, '_')].join(sep);
|
43 | }
|
44 | function loadFontFromFile(fontFamily, font) {
|
45 | const cacheKey = SDK_VERSION >= 26 ? computeFontCacheKey(fontFamily, font) : fontFamily;
|
46 | appAssets = appAssets || ad.getApplicationContext().getAssets();
|
47 | if (!appAssets) {
|
48 | return null;
|
49 | }
|
50 | let result = typefaceCache.get(cacheKey);
|
51 |
|
52 | if (result === undefined) {
|
53 | result = null;
|
54 | let fontAssetPath;
|
55 | const basePath = fs.path.join(fs.knownFolders.currentApp().path, 'fonts', fontFamily);
|
56 | if (fs.File.exists(basePath + '.ttf')) {
|
57 | fontAssetPath = FONTS_BASE_PATH + fontFamily + '.ttf';
|
58 | }
|
59 | else if (fs.File.exists(basePath + '.otf')) {
|
60 | fontAssetPath = FONTS_BASE_PATH + fontFamily + '.otf';
|
61 | }
|
62 | else if (Trace.isEnabled()) {
|
63 | Trace.write('Could not find font file for ' + fontFamily, Trace.categories.Error, Trace.messageType.error);
|
64 | }
|
65 | if (fontAssetPath) {
|
66 | try {
|
67 | fontAssetPath = fs.path.join(fs.knownFolders.currentApp().path, fontAssetPath);
|
68 | if (SDK_VERSION >= 26) {
|
69 | const builder = new android.graphics.Typeface.Builder(fontAssetPath);
|
70 | if (builder) {
|
71 | builder.setFontVariationSettings(font.fontVariationSettings?.length ? FontVariationSettings.toString(font.fontVariationSettings) : '');
|
72 | result = builder.build();
|
73 | }
|
74 | else {
|
75 | result = android.graphics.Typeface.createFromFile(fontAssetPath);
|
76 | if (Trace.isEnabled()) {
|
77 | Trace.write('Could not create builder for ' + fontFamily, Trace.categories.Error, Trace.messageType.error);
|
78 | }
|
79 | }
|
80 | }
|
81 | else {
|
82 | result = android.graphics.Typeface.createFromFile(fontAssetPath);
|
83 | }
|
84 | }
|
85 | catch (e) {
|
86 | if (Trace.isEnabled()) {
|
87 | Trace.write('Error loading font asset: ' + fontAssetPath, Trace.categories.Error, Trace.messageType.error);
|
88 | }
|
89 | }
|
90 | }
|
91 | typefaceCache.set(cacheKey, result);
|
92 | }
|
93 | return result;
|
94 | }
|
95 | function createTypeface(font) {
|
96 | let fontStyle = 0;
|
97 | if (font.isBold) {
|
98 | fontStyle |= android.graphics.Typeface.BOLD;
|
99 | }
|
100 | if (font.isItalic) {
|
101 | fontStyle |= android.graphics.Typeface.ITALIC;
|
102 | }
|
103 |
|
104 | const fontFamilies = parseFontFamily(font.fontFamily);
|
105 | let result = null;
|
106 | for (const fontFamily of fontFamilies) {
|
107 | switch (fontFamily.toLowerCase()) {
|
108 | case genericFontFamilies.serif:
|
109 | result = android.graphics.Typeface.create('serif' + getFontWeightSuffix(font.fontWeight), fontStyle);
|
110 | break;
|
111 | case genericFontFamilies.sansSerif:
|
112 | case genericFontFamilies.system:
|
113 | result = android.graphics.Typeface.create('sans-serif' + getFontWeightSuffix(font.fontWeight), fontStyle);
|
114 | break;
|
115 | case genericFontFamilies.monospace:
|
116 | result = android.graphics.Typeface.create('monospace' + getFontWeightSuffix(font.fontWeight), fontStyle);
|
117 | break;
|
118 | default: {
|
119 | result = loadFontFromFile(fontFamily, font);
|
120 | if (result && fontStyle) {
|
121 | result = android.graphics.Typeface.create(result, fontStyle);
|
122 | }
|
123 | break;
|
124 | }
|
125 | }
|
126 | if (result) {
|
127 |
|
128 | break;
|
129 | }
|
130 | }
|
131 | if (!result) {
|
132 | result = android.graphics.Typeface.create('sans-serif' + getFontWeightSuffix(font.fontWeight), fontStyle);
|
133 | }
|
134 | return result;
|
135 | }
|
136 | function getFontWeightSuffix(fontWeight) {
|
137 | if (typeof fontWeight === 'number') {
|
138 | fontWeight = (fontWeight + '');
|
139 | }
|
140 | switch (fontWeight) {
|
141 | case FontWeight.THIN:
|
142 | return SDK_VERSION >= 16 ? '-thin' : '';
|
143 | case FontWeight.EXTRA_LIGHT:
|
144 | case FontWeight.LIGHT:
|
145 | return SDK_VERSION >= 16 ? '-light' : '';
|
146 | case FontWeight.NORMAL:
|
147 | case '400':
|
148 | case undefined:
|
149 | case null:
|
150 | return '';
|
151 | case FontWeight.MEDIUM:
|
152 | case FontWeight.SEMI_BOLD:
|
153 | return SDK_VERSION >= 21 ? '-medium' : '';
|
154 | case FontWeight.BOLD:
|
155 | case '700':
|
156 | case FontWeight.EXTRA_BOLD:
|
157 | return '';
|
158 | case FontWeight.BLACK:
|
159 | return SDK_VERSION >= 21 ? '-black' : '';
|
160 | default:
|
161 | throw new Error(`Invalid font weight: "${fontWeight}"`);
|
162 | }
|
163 | }
|
164 |
|
\ | No newline at end of file |