UNPKG

@nativescript/core

Version:

A JavaScript library providing an easy to use api for interacting with iOS and Android platform APIs.

226 lines • 8.71 kB
import { Font as FontBase, parseFontFamily, genericFontFamilies, FontWeight, FontVariationSettings, FONTS_BASE_PATH } from './font-common'; import { Trace } from '../../trace'; import { SDK_VERSION } from '../../utils/constants'; import * as fs from '../../file-system'; import { ad } from '../../utils'; export * from './font-common'; const typefaceCache = new Map(); let appAssets; export class Font extends FontBase { withFontFamily(family) { return new Font(family, this.fontSize, this.fontStyle, this.fontWeight, 1, this.fontVariationSettings); } withFontStyle(style) { return new Font(this.fontFamily, this.fontSize, style, this.fontWeight, 1, this.fontVariationSettings); } withFontWeight(weight) { return new Font(this.fontFamily, this.fontSize, this.fontStyle, weight, 1, this.fontVariationSettings); } withFontSize(size) { return new Font(this.fontFamily, size, this.fontStyle, this.fontWeight, 1, this.fontVariationSettings); } withFontScale(scale) { return new Font(this.fontFamily, this.fontSize, this.fontStyle, this.fontWeight, 1, this.fontVariationSettings); } withFontVariationSettings(variationSettings) { return new Font(this.fontFamily, this.fontSize, this.fontStyle, this.fontWeight, 1, variationSettings); } getAndroidTypeface() { if (!this._typeface) { this._typeface = SDK_VERSION >= 28 ? createTypeface(this) : createTypefaceLegacy(this); } return this._typeface; } getUIFont(defaultFont) { return undefined; } } Font.default = new Font(undefined, undefined); function computeFontCacheKey(fontFamily, font) { const sep = ':'; return [fontFamily, String(FontVariationSettings.toString(font.fontVariationSettings)).replace(/'/g, '').replace(/[\s,]/g, '_')].join(sep); } function loadFontFromFile(fontFamily, font) { const cacheKey = SDK_VERSION >= 26 ? computeFontCacheKey(fontFamily, font) : fontFamily; appAssets = appAssets || ad.getApplicationContext().getAssets(); if (!appAssets) { return null; } let result; if (typefaceCache.has(cacheKey)) { result = typefaceCache.get(cacheKey); } else { const basePath = fs.path.join(fs.knownFolders.currentApp().path, FONTS_BASE_PATH, fontFamily); let fontAssetPath; if (fs.File.exists(basePath + '.ttf')) { fontAssetPath = basePath + '.ttf'; } else if (fs.File.exists(basePath + '.otf')) { fontAssetPath = basePath + '.otf'; } else { fontAssetPath = null; if (Trace.isEnabled()) { Trace.write('Could not find font file for ' + fontFamily, Trace.categories.Error, Trace.messageType.error); } } result = null; // Default if (fontAssetPath) { try { if (SDK_VERSION >= 26) { const builder = new android.graphics.Typeface.Builder(fontAssetPath); if (builder) { builder.setFontVariationSettings(font.fontVariationSettings?.length ? FontVariationSettings.toString(font.fontVariationSettings) : ''); result = builder.build(); } else { result = android.graphics.Typeface.createFromFile(fontAssetPath); if (Trace.isEnabled()) { Trace.write('Could not create builder for ' + fontFamily, Trace.categories.Error, Trace.messageType.error); } } } else { result = android.graphics.Typeface.createFromFile(fontAssetPath); } } catch (e) { if (Trace.isEnabled()) { Trace.write('Error loading font asset: ' + fontAssetPath, Trace.categories.Error, Trace.messageType.error); } } } // The value will be null if there has already been an attempt to load the font but failed typefaceCache.set(cacheKey, result); } return result; } function createTypeface(font) { const fontFamilies = parseFontFamily(font.fontFamily); const fontWeightNum = getNumericFontWeight(font.fontWeight); let result; for (const fontFamily of fontFamilies) { switch (fontFamily.toLowerCase()) { case genericFontFamilies.serif: result = android.graphics.Typeface.create(android.graphics.Typeface.SERIF, fontWeightNum, font.isItalic); break; case genericFontFamilies.sansSerif: case genericFontFamilies.system: result = android.graphics.Typeface.create(android.graphics.Typeface.SANS_SERIF, fontWeightNum, font.isItalic); break; case genericFontFamilies.monospace: result = android.graphics.Typeface.create(android.graphics.Typeface.MONOSPACE, fontWeightNum, font.isItalic); break; default: { result = loadFontFromFile(fontFamily, font); if (result) { result = android.graphics.Typeface.create(result, fontWeightNum, font.isItalic); } break; } } // Found the font! if (result) { break; } } if (!result) { result = android.graphics.Typeface.create(android.graphics.Typeface.SANS_SERIF, fontWeightNum, font.isItalic); } return result; } function createTypefaceLegacy(font) { const fontFamilies = parseFontFamily(font.fontFamily); const fontWeight = font.fontWeight; // https://stackoverflow.com/questions/19691530/valid-values-for-androidfontfamily-and-what-they-map-to const fontSuffix = getFontWeightSuffix(fontWeight); let result; let fontStyle = 0; if (font.isBold) { fontStyle |= android.graphics.Typeface.BOLD; } if (font.isItalic) { fontStyle |= android.graphics.Typeface.ITALIC; } for (const fontFamily of fontFamilies) { switch (fontFamily.toLowerCase()) { case genericFontFamilies.serif: result = android.graphics.Typeface.create('serif' + fontSuffix, fontStyle); break; case genericFontFamilies.sansSerif: case genericFontFamilies.system: result = android.graphics.Typeface.create('sans-serif' + fontSuffix, fontStyle); break; case genericFontFamilies.monospace: result = android.graphics.Typeface.create('monospace' + fontSuffix, fontStyle); break; default: { result = loadFontFromFile(fontFamily, font); if (result && fontStyle) { result = android.graphics.Typeface.create(result, fontStyle); } break; } } // Found the font! if (result) { break; } } if (!result) { result = android.graphics.Typeface.create('sans-serif' + fontSuffix, fontStyle); } return result; } function getFontWeightSuffix(fontWeight) { if (typeof fontWeight === 'number') { fontWeight = (fontWeight + ''); } switch (fontWeight) { case FontWeight.THIN: return SDK_VERSION >= 16 ? '-thin' : ''; case FontWeight.EXTRA_LIGHT: case FontWeight.LIGHT: return SDK_VERSION >= 16 ? '-light' : ''; case FontWeight.NORMAL: case '400': case undefined: case null: return ''; case FontWeight.MEDIUM: case FontWeight.SEMI_BOLD: return SDK_VERSION >= 21 ? '-medium' : ''; case FontWeight.BOLD: case '700': case FontWeight.EXTRA_BOLD: return ''; case FontWeight.BLACK: return SDK_VERSION >= 21 ? '-black' : ''; default: throw new Error(`Invalid font weight: "${fontWeight}"`); } } function getNumericFontWeight(fontWeight) { let value; if (typeof fontWeight === 'number') { value = fontWeight; } else { switch (fontWeight) { case FontWeight.NORMAL: case undefined: case null: value = 400; break; case FontWeight.BOLD: value = 700; break; default: value = parseInt(fontWeight); break; } } return value; } //# sourceMappingURL=font.android.js.map