mirror of
https://github.com/NativeScript/NativeScript.git
synced 2025-08-16 20:11:24 +08:00
Font-family fallback
This commit is contained in:
@ -3,9 +3,12 @@
|
||||
<StackLayout id="stack">
|
||||
<Button text="RESET" tap="buttonTap"/>
|
||||
|
||||
<Label text="Fallback: times or serif" style="font-family: invalid, 'one more invalid font', , Times New Roman, serif"/>
|
||||
<Label text="Fallback: monospace" style="font-family: invalid, Courier New, monospace"/>
|
||||
<Label text="Fallback: monospace bold italic" style="font-family: invalid, CourierNewPS-BoldItalicMT, monospace; font-weight: bold; font-style: italic;"/>
|
||||
|
||||
<Label text="GREEN" style="color: green" />
|
||||
<Button text="GREEN" style="color: green"/>
|
||||
<Button text="GREEN" style="color: green"/>c
|
||||
<TextView text="GREEN" style="color: green"/>
|
||||
<TextField text="GREEN" style="color: green"/>
|
||||
|
||||
|
@ -70,6 +70,22 @@ export class Font implements definitios.Font {
|
||||
}
|
||||
}
|
||||
|
||||
export function parseFontFamily(value: string): Array<string> {
|
||||
var result = new Array<string>();
|
||||
if (!value) {
|
||||
return result;
|
||||
}
|
||||
|
||||
var split = value.split(",");
|
||||
for (var i = 0; i < split.length; i++) {
|
||||
var str = split[i].trim().replace(/['"]+/g, '');
|
||||
if (str) {
|
||||
result.push(str);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
export module genericFontFamilies {
|
||||
export var serif = "serif";
|
||||
export var sansSerif = "sans-serif";
|
||||
|
@ -3,6 +3,7 @@ import common = require("ui/styling/font-common");
|
||||
import application = require("application");
|
||||
import trace = require("trace");
|
||||
import types = require("utils/types");
|
||||
import fs = require("file-system");
|
||||
|
||||
var typefaceCache = new Map<string, android.graphics.Typeface>();
|
||||
var appAssets: android.content.res.AssetManager;
|
||||
@ -46,23 +47,37 @@ export class Font extends common.Font {
|
||||
}
|
||||
|
||||
private getTypeFace(fontFamily: string): android.graphics.Typeface {
|
||||
if (!fontFamily) {
|
||||
var fonts = common.parseFontFamily(fontFamily);
|
||||
var result = null;
|
||||
if (fonts.length === 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
switch (fontFamily.toLowerCase()) {
|
||||
case common.genericFontFamilies.serif:
|
||||
return android.graphics.Typeface.SERIF;
|
||||
for (var i = 0; i < fonts.length; i++) {
|
||||
switch (fonts[i].toLowerCase()) {
|
||||
case common.genericFontFamilies.serif:
|
||||
result = android.graphics.Typeface.SERIF;
|
||||
break;
|
||||
|
||||
case common.genericFontFamilies.sansSerif:
|
||||
return android.graphics.Typeface.SANS_SERIF;
|
||||
case common.genericFontFamilies.sansSerif:
|
||||
result = android.graphics.Typeface.SANS_SERIF;
|
||||
break;
|
||||
|
||||
case common.genericFontFamilies.monospace:
|
||||
return android.graphics.Typeface.MONOSPACE;
|
||||
case common.genericFontFamilies.monospace:
|
||||
result = android.graphics.Typeface.MONOSPACE;
|
||||
break;
|
||||
|
||||
default:
|
||||
return this.loadFontFromAsset(fontFamily);
|
||||
default:
|
||||
result = this.loadFontFromAsset(fonts[i]);
|
||||
break;
|
||||
}
|
||||
|
||||
if (result) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private loadFontFromAsset(fontFamily: string): android.graphics.Typeface {
|
||||
@ -75,11 +90,24 @@ export class Font extends common.Font {
|
||||
// Check for undefined explicitly as null mean we tried to load the font, but failed.
|
||||
if (types.isUndefined(result)) {
|
||||
result = null;
|
||||
var fontAsset = "app/fonts/" + fontFamily + ".ttf";
|
||||
try {
|
||||
result = android.graphics.Typeface.createFromAsset(appAssets, fontAsset);
|
||||
} catch (e) {
|
||||
trace.write("Cannot find font asset: " + fontAsset, trace.categories.Error, trace.messageType.error);
|
||||
var fontAssetPath: string;
|
||||
var basePath = fs.path.join(fs.knownFolders.currentApp().path, "fonts", fontFamily);
|
||||
if (fs.File.exists(basePath + ".ttf")) {
|
||||
fontAssetPath = "app/fonts/" + fontFamily + ".ttf";
|
||||
}
|
||||
else if (fs.File.exists(basePath + ".otf")) {
|
||||
fontAssetPath = "app/fonts/" + fontFamily + ".otf";
|
||||
}
|
||||
else {
|
||||
trace.write("Could not find font file for " + fontFamily, trace.categories.Error, trace.messageType.error);
|
||||
}
|
||||
|
||||
if (fontAssetPath){
|
||||
try {
|
||||
result = android.graphics.Typeface.createFromAsset(appAssets, fontAssetPath);
|
||||
} catch (e) {
|
||||
trace.write("Error loading font asset: " + fontAssetPath, trace.categories.Error, trace.messageType.error);
|
||||
}
|
||||
}
|
||||
typefaceCache.set(fontFamily, result);
|
||||
}
|
||||
|
@ -1,19 +1,34 @@
|
||||
import enums = require("ui/enums");
|
||||
import common = require("ui/styling/font-common");
|
||||
import utils = require("utils/utils");
|
||||
|
||||
var DEFAULT_SERIF = "Times New Roman";
|
||||
var DEFAULT_SANS_SERIF = "Helvetica";
|
||||
var DEFAULT_MONOSPACE = "Courier New";
|
||||
|
||||
var systemFontFamilies = new Set();
|
||||
var systemFonts = new Set();
|
||||
|
||||
function initSystemFotns() {
|
||||
var nsFontFamilies = UIFont.familyNames();
|
||||
for (var i = 0; i < nsFontFamilies.count; i++) {
|
||||
var family = nsFontFamilies.objectAtIndex(i);
|
||||
systemFontFamilies.add(family);
|
||||
|
||||
var nsFonts = UIFont.fontNamesForFamilyName(family);
|
||||
for (var j = 0; j < nsFonts.count; j++) {
|
||||
var font = nsFonts.objectAtIndex(j);
|
||||
systemFonts.add(font);
|
||||
}
|
||||
}
|
||||
}
|
||||
initSystemFotns();
|
||||
|
||||
export class Font extends common.Font {
|
||||
public static default = new Font(undefined, enums.FontStyle.normal, enums.FontWeight.normal);
|
||||
|
||||
private _ios: UIFontDescriptor;
|
||||
get ios(): UIFontDescriptor {
|
||||
if (!this._ios) {
|
||||
var fontFamily = this.getFontFamilyRespectingGenericFonts(this.fontFamily);
|
||||
|
||||
var symbolicTraits: number = 0;
|
||||
if (this.isBold) {
|
||||
symbolicTraits |= UIFontDescriptorSymbolicTraits.UIFontDescriptorTraitBold;
|
||||
@ -22,14 +37,9 @@ export class Font extends common.Font {
|
||||
symbolicTraits |= UIFontDescriptorSymbolicTraits.UIFontDescriptorTraitItalic;
|
||||
}
|
||||
|
||||
if (fontFamily) {
|
||||
this._ios = UIFontDescriptor.fontDescriptorWithNameSize(fontFamily, 0);
|
||||
if (symbolicTraits) {
|
||||
this._ios = this._ios.fontDescriptorWithSymbolicTraits(symbolicTraits);
|
||||
}
|
||||
}
|
||||
this._ios = resolveFontDescriptor(this.fontFamily, symbolicTraits);
|
||||
|
||||
if(!this._ios) {
|
||||
if (!this._ios) {
|
||||
this._ios = UIFontDescriptor.new().fontDescriptorWithSymbolicTraits(symbolicTraits);
|
||||
}
|
||||
}
|
||||
@ -51,25 +61,56 @@ export class Font extends common.Font {
|
||||
public withFontWeight(weight: string): Font {
|
||||
return new Font(this.fontFamily, this.fontStyle, weight);
|
||||
}
|
||||
|
||||
private getFontFamilyRespectingGenericFonts(fontFamily: string): string {
|
||||
if (!fontFamily) {
|
||||
return fontFamily;
|
||||
}
|
||||
|
||||
switch (fontFamily.toLowerCase()) {
|
||||
case common.genericFontFamilies.serif:
|
||||
return DEFAULT_SERIF;
|
||||
|
||||
case common.genericFontFamilies.sansSerif:
|
||||
return DEFAULT_SANS_SERIF;
|
||||
|
||||
case common.genericFontFamilies.monospace:
|
||||
return DEFAULT_MONOSPACE;
|
||||
|
||||
default:
|
||||
return fontFamily;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function resolveFontDescriptor(fontFamilyValue: string, symbolicTraits: number): UIFontDescriptor {
|
||||
var fonts = common.parseFontFamily(fontFamilyValue);
|
||||
var result: UIFontDescriptor = null;
|
||||
if (fonts.length === 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
for (var i = 0; i < fonts.length; i++) {
|
||||
var fontFamily = getFontFamilyRespectingGenericFonts(fonts[i]);
|
||||
if (systemFontFamilies.has(fontFamily)) {
|
||||
// This is a font family - we should apply symbolic traits if there are such
|
||||
result = UIFontDescriptor.fontDescriptorWithNameSize(fontFamily, 0);
|
||||
if (symbolicTraits) {
|
||||
result = result.fontDescriptorWithSymbolicTraits(symbolicTraits);
|
||||
}
|
||||
}
|
||||
else if (systemFonts.has(fontFamily)) {
|
||||
// This is an actual font - don't apply symbolic traits
|
||||
result = UIFontDescriptor.fontDescriptorWithNameSize(fontFamily, 0);
|
||||
}
|
||||
else {
|
||||
// TODO: Handle custom fonts when they are supported.
|
||||
}
|
||||
|
||||
if (result) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
function getFontFamilyRespectingGenericFonts(fontFamily: string): string {
|
||||
if (!fontFamily) {
|
||||
return fontFamily;
|
||||
}
|
||||
|
||||
switch (fontFamily.toLowerCase()) {
|
||||
case common.genericFontFamilies.serif:
|
||||
return DEFAULT_SERIF;
|
||||
|
||||
case common.genericFontFamilies.sansSerif:
|
||||
return DEFAULT_SANS_SERIF;
|
||||
|
||||
case common.genericFontFamilies.monospace:
|
||||
return DEFAULT_MONOSPACE;
|
||||
|
||||
default:
|
||||
return fontFamily;
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user