mirror of
https://github.com/NativeScript/NativeScript.git
synced 2025-11-05 13:26:48 +08:00
Add parsers for the background css shorthand property, make ViewBase unit testable in node environment
Add background parser and linear-gradient parser
Use sticky regexes
Simplify some types, introduce generic Parsed<T> instead of & TokenRange
Apply each parser to return a { start, end, value } object
Move the css selector parser to the css/parser and unify types
Add the first steps toward building homegrown css parser
Add somewhat standards compliant tokenizer, add baseline, rework and shady css parsers
Enable all tests again, skip flaky perf test
Improve css parser tokenizer by converting some char token types to simple string
Implement 'parse a stylesheet'
Add gonzales css-parser
Add parseLib and css-tree perf
Add a thin parser layer that will convert CSS3 tokens to values, for now output is compatible with rework
Make root tsc green
Return the requires of tns-core-modules to use relative paths for webpack to work
Implement support for '@import 'url-string';
Fix function parser, function-token is no-longer neglected
Make the style-scope be able to load from "css" and "css-ast" modules
Add a loadAppCss event so theme can be added to snapshot separately from loaded
163 lines
5.6 KiB
TypeScript
163 lines
5.6 KiB
TypeScript
import { Font as FontBase, parseFontFamily, genericFontFamilies, FontWeight } from "./font-common";
|
|
import { isEnabled as traceEnabled, write as traceWrite, categories as traceCategories, messageType as traceMessageType } from "../../trace";
|
|
import * as application from "../../application";
|
|
import * as fs from "../../file-system";
|
|
|
|
export * from "./font-common";
|
|
|
|
const FONTS_BASE_PATH = "/fonts/";
|
|
const typefaceCache = new Map<string, android.graphics.Typeface>();
|
|
let appAssets: android.content.res.AssetManager;
|
|
|
|
export class Font extends FontBase {
|
|
public static default = new Font(undefined, undefined, "normal", "normal");
|
|
|
|
private _typeface: android.graphics.Typeface;
|
|
|
|
constructor(family: string, size: number, style: "normal" | "italic", weight: FontWeight) {
|
|
super(family, size, style, weight);
|
|
}
|
|
|
|
public withFontFamily(family: string): Font {
|
|
return new Font(family, this.fontSize, this.fontStyle, this.fontWeight);
|
|
}
|
|
|
|
public withFontStyle(style: "normal" | "italic"): Font {
|
|
return new Font(this.fontFamily, this.fontSize, style, this.fontWeight);
|
|
}
|
|
|
|
public withFontWeight(weight: FontWeight): Font {
|
|
return new Font(this.fontFamily, this.fontSize, this.fontStyle, weight);
|
|
}
|
|
|
|
public withFontSize(size: number): Font {
|
|
return new Font(this.fontFamily, size, this.fontStyle, this.fontWeight);
|
|
}
|
|
|
|
public getAndroidTypeface(): android.graphics.Typeface {
|
|
if (!this._typeface) {
|
|
this._typeface = createTypeface(this);
|
|
}
|
|
return this._typeface;
|
|
}
|
|
|
|
public getUIFont(defaultFont: UIFont): UIFont {
|
|
return undefined;
|
|
}
|
|
}
|
|
|
|
function loadFontFromFile(fontFamily: string): android.graphics.Typeface {
|
|
appAssets = appAssets || application.android.context.getAssets();
|
|
if (!appAssets) {
|
|
return null;
|
|
}
|
|
|
|
let result = typefaceCache.get(fontFamily);
|
|
// Check for undefined explicitly as null mean we tried to load the font, but failed.
|
|
if (result === undefined) {
|
|
result = null;
|
|
|
|
let fontAssetPath: string;
|
|
const basePath = fs.path.join(fs.knownFolders.currentApp().path, "fonts", fontFamily);
|
|
if (fs.File.exists(basePath + ".ttf")) {
|
|
fontAssetPath = FONTS_BASE_PATH + fontFamily + ".ttf";
|
|
}
|
|
else if (fs.File.exists(basePath + ".otf")) {
|
|
fontAssetPath = FONTS_BASE_PATH + fontFamily + ".otf";
|
|
}
|
|
else {
|
|
if (traceEnabled()) {
|
|
traceWrite("Could not find font file for " + fontFamily, traceCategories.Error, traceMessageType.error);
|
|
}
|
|
}
|
|
|
|
if (fontAssetPath) {
|
|
try {
|
|
fontAssetPath = fs.path.join(fs.knownFolders.currentApp().path, fontAssetPath);
|
|
result = android.graphics.Typeface.createFromFile(fontAssetPath);
|
|
} catch (e) {
|
|
if (traceEnabled()) {
|
|
traceWrite("Error loading font asset: " + fontAssetPath, traceCategories.Error, traceMessageType.error);
|
|
}
|
|
}
|
|
}
|
|
typefaceCache.set(fontFamily, result);
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
function createTypeface(font: Font): android.graphics.Typeface {
|
|
let fontStyle = 0;
|
|
if (font.isBold) {
|
|
fontStyle |= android.graphics.Typeface.BOLD;
|
|
}
|
|
if (font.isItalic) {
|
|
fontStyle |= android.graphics.Typeface.ITALIC;
|
|
}
|
|
|
|
//http://stackoverflow.com/questions/19691530/valid-values-for-androidfontfamily-and-what-they-map-to
|
|
const fonts = parseFontFamily(font.fontFamily);
|
|
let result = null;
|
|
for (let i = 0; i < fonts.length; i++) {
|
|
switch (fonts[i].toLowerCase()) {
|
|
case genericFontFamilies.serif:
|
|
result = android.graphics.Typeface.create("serif" + getFontWeightSuffix(font.fontWeight), fontStyle);
|
|
break;
|
|
|
|
case genericFontFamilies.sansSerif:
|
|
case genericFontFamilies.system:
|
|
result = android.graphics.Typeface.create("sans-serif" + getFontWeightSuffix(font.fontWeight), fontStyle);
|
|
break;
|
|
|
|
case genericFontFamilies.monospace:
|
|
result = android.graphics.Typeface.create("monospace" + getFontWeightSuffix(font.fontWeight), fontStyle);
|
|
break;
|
|
|
|
default:
|
|
result = loadFontFromFile(fonts[i]);
|
|
if (result && fontStyle) {
|
|
result = android.graphics.Typeface.create(result, fontStyle);
|
|
}
|
|
break;
|
|
}
|
|
|
|
if (result) {
|
|
// Found the font!
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (!result) {
|
|
result = android.graphics.Typeface.create("sans-serif" + getFontWeightSuffix(font.fontWeight), fontStyle);
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
function getFontWeightSuffix(fontWeight: FontWeight): string {
|
|
switch (fontWeight) {
|
|
case FontWeight.THIN:
|
|
return android.os.Build.VERSION.SDK_INT >= 16 ? "-thin" : "";
|
|
case FontWeight.EXTRA_LIGHT:
|
|
case FontWeight.LIGHT:
|
|
return android.os.Build.VERSION.SDK_INT >= 16 ? "-light" : "";
|
|
case FontWeight.NORMAL:
|
|
case "400":
|
|
case undefined:
|
|
case null:
|
|
return "";
|
|
case FontWeight.MEDIUM:
|
|
case FontWeight.SEMI_BOLD:
|
|
return android.os.Build.VERSION.SDK_INT >= 21 ? "-medium" : "";
|
|
case FontWeight.BOLD:
|
|
case "700":
|
|
case FontWeight.EXTRA_BOLD:
|
|
return "";
|
|
case FontWeight.BLACK:
|
|
return android.os.Build.VERSION.SDK_INT >= 21 ? "-black" : "";
|
|
default:
|
|
throw new Error(`Invalid font weight: "${fontWeight}"`);
|
|
}
|
|
}
|