mirror of
https://github.com/NativeScript/NativeScript.git
synced 2025-11-05 13:26:48 +08:00
Reworked fonts logic
This commit is contained in:
@@ -4,9 +4,10 @@ import { StackLayout } from "ui/layouts/stack-layout";
|
|||||||
import { ScrollView } from "ui/scroll-view";
|
import { ScrollView } from "ui/scroll-view";
|
||||||
import { Label } from "ui/label";
|
import { Label } from "ui/label";
|
||||||
import { FontStyle, FontWeight } from "ui/enums";
|
import { FontStyle, FontWeight } from "ui/enums";
|
||||||
import typeUtils = require("utils/types");
|
import * as typeUtils from "utils/types";
|
||||||
import { Color } from "color";
|
import { Color } from "color";
|
||||||
import * as font from "ui/styling/font";
|
import * as utils from "utils/utils";
|
||||||
|
import { isIOS } from "platform";
|
||||||
|
|
||||||
const genericFontFamilies = [
|
const genericFontFamilies = [
|
||||||
"system",
|
"system",
|
||||||
@@ -14,8 +15,8 @@ const genericFontFamilies = [
|
|||||||
"serif",
|
"serif",
|
||||||
"monospace",
|
"monospace",
|
||||||
];
|
];
|
||||||
var fontFamilies = [];
|
let fontFamilies = [];
|
||||||
var fontNames = [];
|
let fontNames = [];
|
||||||
const embeddedFontNames = [
|
const embeddedFontNames = [
|
||||||
"FontAwesome",
|
"FontAwesome",
|
||||||
"Pacifico",
|
"Pacifico",
|
||||||
@@ -37,34 +38,36 @@ const fontWeights = [
|
|||||||
FontWeight.black,
|
FontWeight.black,
|
||||||
];
|
];
|
||||||
|
|
||||||
var green = new Color("Green");
|
let green = new Color("Green");
|
||||||
var red = new Color("Red");
|
let red = new Color("Red");
|
||||||
var white = new Color("White");
|
let white = new Color("White");
|
||||||
var black = new Color("Black");
|
let black = new Color("Black");
|
||||||
|
|
||||||
var compareIgnoreCase = function (a, b) {
|
let compareIgnoreCase = function (a, b) {
|
||||||
return a.toLowerCase().localeCompare(b.toLowerCase());
|
return a.toLowerCase().localeCompare(b.toLowerCase());
|
||||||
};
|
};
|
||||||
|
|
||||||
if (font.ios) {
|
if (isIOS) {
|
||||||
// for (var f = 0; f < embeddedFontNames.length; f++) {
|
const nsFontFamilies = utils.ios.getter(UIFont, UIFont.familyNames);
|
||||||
// font.ios.registerFont(`fonts/${embeddedFontNames[f]}.ttf`);
|
for (let i = 0; i < nsFontFamilies.count; i++) {
|
||||||
// }
|
const family = nsFontFamilies.objectAtIndex(i);
|
||||||
|
fontFamilies.push(family)
|
||||||
|
|
||||||
var font_internal = <any>font;
|
const nsFonts = UIFont.fontNamesForFamilyName(family);
|
||||||
font_internal.ensureSystemFontSets();
|
for (let j = 0; j < nsFonts.count; j++) {
|
||||||
|
const font = nsFonts.objectAtIndex(j);
|
||||||
|
fontNames.push(font)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
(<Set<string>>font_internal.systemFontFamilies).forEach(f => fontFamilies.push(f));
|
|
||||||
fontFamilies = fontFamilies.sort(compareIgnoreCase);
|
fontFamilies = fontFamilies.sort(compareIgnoreCase);
|
||||||
|
|
||||||
(<Set<string>>font_internal.systemFonts).forEach(f => fontNames.push(f));
|
|
||||||
fontNames = fontNames.sort(compareIgnoreCase);
|
fontNames = fontNames.sort(compareIgnoreCase);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function onPageLoaded(args: NavigatedData) {
|
export function onPageLoaded(args: NavigatedData) {
|
||||||
var page = <Page>args.object;
|
let page = <Page>args.object;
|
||||||
var scrollView = new ScrollView();
|
let scrollView = new ScrollView();
|
||||||
var stackLayout = new StackLayout();
|
let stackLayout = new StackLayout();
|
||||||
generateLabels(stackLayout);
|
generateLabels(stackLayout);
|
||||||
scrollView.content = stackLayout;
|
scrollView.content = stackLayout;
|
||||||
page.content = scrollView;
|
page.content = scrollView;
|
||||||
@@ -72,25 +75,24 @@ export function onPageLoaded(args: NavigatedData) {
|
|||||||
|
|
||||||
function generateLabels(layout: StackLayout) {
|
function generateLabels(layout: StackLayout) {
|
||||||
layout.addChild(prepareTitle("Generic Font Families", 24));
|
layout.addChild(prepareTitle("Generic Font Families", 24));
|
||||||
for (var f = 0; f < genericFontFamilies.length; f++) {
|
for (let f = 0; f < genericFontFamilies.length; f++) {
|
||||||
layout.addChild(prepareTitle(genericFontFamilies[f], 20));
|
layout.addChild(prepareTitle(genericFontFamilies[f], 20));
|
||||||
for (var s = 0; s < fontStyles.length; s++) {
|
for (let s = 0; s < fontStyles.length; s++) {
|
||||||
for (var w = 0; w < fontWeights.length; w++) {
|
for (let w = 0; w < fontWeights.length; w++) {
|
||||||
var view = prepareLabel(genericFontFamilies[f], fontStyles[s], fontWeights[w]);
|
let view = prepareLabel(genericFontFamilies[f], fontStyles[s], fontWeights[w]);
|
||||||
layout.addChild(view);
|
layout.addChild(view);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fontFamilies.length > 0)
|
if (fontFamilies.length > 0) {
|
||||||
{
|
|
||||||
layout.addChild(prepareTitle("Font Families", 24));
|
layout.addChild(prepareTitle("Font Families", 24));
|
||||||
}
|
}
|
||||||
for (var f = 0; f < fontFamilies.length; f++) {
|
for (let f = 0; f < fontFamilies.length; f++) {
|
||||||
layout.addChild(prepareTitle(fontFamilies[f], 20));
|
layout.addChild(prepareTitle(fontFamilies[f], 20));
|
||||||
for (var s = 0; s < fontStyles.length; s++) {
|
for (let s = 0; s < fontStyles.length; s++) {
|
||||||
for (var w = 0; w < fontWeights.length; w++) {
|
for (let w = 0; w < fontWeights.length; w++) {
|
||||||
var view = prepareLabel(fontFamilies[f], fontStyles[s], fontWeights[w]);
|
let view = prepareLabel(fontFamilies[f], fontStyles[s], fontWeights[w]);
|
||||||
layout.addChild(view);
|
layout.addChild(view);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -99,22 +101,22 @@ function generateLabels(layout: StackLayout) {
|
|||||||
if (fontNames.length > 0) {
|
if (fontNames.length > 0) {
|
||||||
layout.addChild(prepareTitle("Phone Fonts", 24));
|
layout.addChild(prepareTitle("Phone Fonts", 24));
|
||||||
}
|
}
|
||||||
for (var f = 0; f < fontNames.length; f++) {
|
for (let f = 0; f < fontNames.length; f++) {
|
||||||
var view = prepareLabel(fontNames[f], "normal", "normal");
|
let view = prepareLabel(fontNames[f], "normal", "normal");
|
||||||
layout.addChild(view);
|
layout.addChild(view);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (embeddedFontNames.length > 0) {
|
if (embeddedFontNames.length > 0) {
|
||||||
layout.addChild(prepareTitle("Embedded Fonts", 24));
|
layout.addChild(prepareTitle("Embedded Fonts", 24));
|
||||||
}
|
}
|
||||||
for (var f = 0; f < embeddedFontNames.length; f++) {
|
for (let f = 0; f < embeddedFontNames.length; f++) {
|
||||||
var view = prepareLabel(embeddedFontNames[f], "normal", "normal");
|
let view = prepareLabel(embeddedFontNames[f], "normal", "normal");
|
||||||
layout.addChild(view);
|
layout.addChild(view);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function prepareTitle(text: string, fontSize: number) {
|
function prepareTitle(text: string, fontSize: number) {
|
||||||
var title = new Label();
|
let title = new Label();
|
||||||
title.text = text;
|
title.text = text;
|
||||||
title.height = 100;
|
title.height = 100;
|
||||||
title.backgroundColor = black;
|
title.backgroundColor = black;
|
||||||
@@ -128,12 +130,12 @@ function prepareTitle(text: string, fontSize: number) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function prepareLabel(fontFamily: string, fontStyle: string, fontWeight: string): View {
|
function prepareLabel(fontFamily: string, fontStyle: string, fontWeight: string): View {
|
||||||
var label = new Label();
|
let label = new Label();
|
||||||
label["font-family"] = fontFamily;
|
label["font-family"] = fontFamily;
|
||||||
var fontFamilyCss = `font-family: ${fontFamily}; `;
|
let fontFamilyCss = `font-family: ${fontFamily}; `;
|
||||||
var fontStyleCss = fontStyle !== FontStyle.normal ? `font-style: ${fontStyle}; ` : "";
|
let fontStyleCss = fontStyle !== FontStyle.normal ? `font-style: ${fontStyle}; ` : "";
|
||||||
var fontWeightCss = fontWeight !== FontWeight.normal ? `font-weight: ${fontWeight}; ` : "";
|
let fontWeightCss = fontWeight !== FontWeight.normal ? `font-weight: ${fontWeight}; ` : "";
|
||||||
var css = `${fontFamilyCss}${fontStyleCss}${fontWeightCss}`;
|
let css = `${fontFamilyCss}${fontStyleCss}${fontWeightCss}`;
|
||||||
label.text = `${typeUtils.getClass(label)} {${css}};`;
|
label.text = `${typeUtils.getClass(label)} {${css}};`;
|
||||||
label.textWrap = true;
|
label.textWrap = true;
|
||||||
label.style.textAlignment = "left";
|
label.style.textAlignment = "left";
|
||||||
@@ -142,9 +144,9 @@ function prepareLabel(fontFamily: string, fontStyle: string, fontWeight: string)
|
|||||||
label.style.padding = "2";
|
label.style.padding = "2";
|
||||||
label.setInlineStyle(css);
|
label.setInlineStyle(css);
|
||||||
label.on("loaded", args => {
|
label.on("loaded", args => {
|
||||||
var sender = <Label>args.object;
|
let sender = <Label>args.object;
|
||||||
if (sender.ios) {
|
if (sender.ios) {
|
||||||
var uiFont = _getUIFont(label);
|
let uiFont = _getUIFont(label);
|
||||||
sender.text += `\niOS Font: ${uiFont.fontName};`;
|
sender.text += `\niOS Font: ${uiFont.fontName};`;
|
||||||
if (genericFontFamilies.indexOf(fontFamily) !== -1) {
|
if (genericFontFamilies.indexOf(fontFamily) !== -1) {
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -39,8 +39,13 @@ export class Font implements definitios.Font {
|
|||||||
}
|
}
|
||||||
|
|
||||||
get isBold(): boolean {
|
get isBold(): boolean {
|
||||||
return this._fontWeight.toLowerCase() === enums.FontWeight.bold
|
const val = this._fontWeight.toLowerCase();
|
||||||
|| this._fontWeight.toLowerCase() === "700";
|
|
||||||
|
return val === enums.FontWeight.semiBold ||
|
||||||
|
val === enums.FontWeight.bold ||
|
||||||
|
val === "700" ||
|
||||||
|
val === enums.FontWeight.extraBold ||
|
||||||
|
val === enums.FontWeight.black;
|
||||||
}
|
}
|
||||||
set isBold(value: boolean) {
|
set isBold(value: boolean) {
|
||||||
throw new Error("isBold is read-only");
|
throw new Error("isBold is read-only");
|
||||||
|
|||||||
@@ -64,16 +64,7 @@ export class Font extends common.Font {
|
|||||||
|
|
||||||
public getAndroidTypeface(): android.graphics.Typeface {
|
public getAndroidTypeface(): android.graphics.Typeface {
|
||||||
if (!this._typeface) {
|
if (!this._typeface) {
|
||||||
var fontStyle = 0;
|
this._typeface = createTypeface(this);
|
||||||
if (this.isBold) {
|
|
||||||
fontStyle |= android.graphics.Typeface.BOLD;
|
|
||||||
}
|
|
||||||
if (this.isItalic) {
|
|
||||||
fontStyle |= android.graphics.Typeface.ITALIC;
|
|
||||||
}
|
|
||||||
|
|
||||||
var typeFace = createTypeface(this);
|
|
||||||
this._typeface = android.graphics.Typeface.create(typeFace, fontStyle);
|
|
||||||
}
|
}
|
||||||
return this._typeface;
|
return this._typeface;
|
||||||
}
|
}
|
||||||
@@ -128,40 +119,47 @@ function loadFontFromFile(fontFamily: string): android.graphics.Typeface {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function createTypeface(font: Font): android.graphics.Typeface {
|
function createTypeface(font: Font): android.graphics.Typeface {
|
||||||
//http://stackoverflow.com/questions/19691530/valid-values-for-androidfontfamily-and-what-they-map-to
|
let fontStyle = 0;
|
||||||
var fonts = common.parseFontFamily(font.fontFamily);
|
if (font.isBold) {
|
||||||
var result = null;
|
fontStyle |= android.graphics.Typeface.BOLD;
|
||||||
if (fonts.length === 0) {
|
}
|
||||||
return null;
|
if (font.isItalic) {
|
||||||
|
fontStyle |= android.graphics.Typeface.ITALIC;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (var i = 0; i < fonts.length; i++) {
|
//http://stackoverflow.com/questions/19691530/valid-values-for-androidfontfamily-and-what-they-map-to
|
||||||
|
const fonts = common.parseFontFamily(font.fontFamily);
|
||||||
|
let result = null;
|
||||||
|
for (let i = 0; i < fonts.length && !result; i++) {
|
||||||
switch (fonts[i].toLowerCase()) {
|
switch (fonts[i].toLowerCase()) {
|
||||||
case common.genericFontFamilies.serif:
|
case common.genericFontFamilies.serif:
|
||||||
result = android.graphics.Typeface.create("serif" + getFontWeightSuffix(font.fontWeight), 0);
|
result = android.graphics.Typeface.create("serif" + getFontWeightSuffix(font.fontWeight), fontStyle);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case common.genericFontFamilies.sansSerif:
|
case common.genericFontFamilies.sansSerif:
|
||||||
case common.genericFontFamilies.system:
|
case common.genericFontFamilies.system:
|
||||||
result = android.graphics.Typeface.create("sans-serif" + getFontWeightSuffix(font.fontWeight), 0);
|
result = android.graphics.Typeface.create("sans-serif" + getFontWeightSuffix(font.fontWeight), fontStyle);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case common.genericFontFamilies.monospace:
|
case common.genericFontFamilies.monospace:
|
||||||
result = android.graphics.Typeface.create("monospace" + getFontWeightSuffix(font.fontWeight), 0);
|
result = android.graphics.Typeface.create("monospace" + getFontWeightSuffix(font.fontWeight), fontStyle);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
result = loadFontFromFile(fonts[i]);
|
result = loadFontFromFile(fonts[i]);
|
||||||
|
if (fontStyle) {
|
||||||
|
result = android.graphics.Typeface.create(result, fontStyle);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fontStyle && !result) {
|
||||||
|
result = android.graphics.Typeface.create("sans-serif" + getFontWeightSuffix(font.fontWeight), fontStyle);
|
||||||
|
}
|
||||||
|
|
||||||
if (result) {
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
function getFontWeightSuffix(fontWeight: string): string {
|
function getFontWeightSuffix(fontWeight: string): string {
|
||||||
switch (fontWeight) {
|
switch (fontWeight) {
|
||||||
|
|||||||
@@ -2,8 +2,14 @@
|
|||||||
import common = require("./font-common");
|
import common = require("./font-common");
|
||||||
import fs = require("file-system");
|
import fs = require("file-system");
|
||||||
import * as traceModule from "trace";
|
import * as traceModule from "trace";
|
||||||
|
|
||||||
import * as utils from "utils/utils";
|
import * as utils from "utils/utils";
|
||||||
|
import { device } from "platform"
|
||||||
|
|
||||||
|
const EMULATE_OBLIQUE = true;
|
||||||
|
const OBLIQUE_TRANSFORM = CGAffineTransformMake(1, 0, 0.2, 1, 0, 0);
|
||||||
|
const DEFAULT_SERIF = "Times New Roman";
|
||||||
|
const DEFAULT_MONOSPACE = "Courier New";
|
||||||
|
const SUPPORT_FONT_WEIGHTS = parseFloat(device.osVersion) >= 10.0;
|
||||||
|
|
||||||
export class Font extends common.Font {
|
export class Font extends common.Font {
|
||||||
public static default = new Font(undefined, undefined, enums.FontStyle.normal, enums.FontWeight.normal);
|
public static default = new Font(undefined, undefined, enums.FontStyle.normal, enums.FontWeight.normal);
|
||||||
@@ -38,160 +44,18 @@ export class Font extends common.Font {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var areSystemFontSetsValid: boolean = false;
|
function shouldUseSystemFont(fontFamily: string) {
|
||||||
export var systemFontFamilies = new Set<string>();
|
return !fontFamily ||
|
||||||
export var systemFonts = new Set<string>();
|
fontFamily === common.genericFontFamilies.sansSerif ||
|
||||||
|
fontFamily === common.genericFontFamilies.system;
|
||||||
export function ensureSystemFontSets() {
|
|
||||||
if (areSystemFontSetsValid) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var nsFontFamilies = utils.ios.getter(UIFont, 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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
areSystemFontSetsValid = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
const DEFAULT_SERIF = "Times New Roman";
|
|
||||||
const DEFAULT_MONOSPACE = "Courier New";
|
|
||||||
|
|
||||||
function getFontFamilyRespectingGenericFonts(fontFamily: string): string {
|
|
||||||
if (!fontFamily) {
|
|
||||||
return fontFamily;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (fontFamily.toLowerCase()) {
|
|
||||||
case common.genericFontFamilies.serif:
|
|
||||||
return DEFAULT_SERIF;
|
|
||||||
|
|
||||||
case common.genericFontFamilies.monospace:
|
|
||||||
return DEFAULT_MONOSPACE;
|
|
||||||
|
|
||||||
default:
|
|
||||||
return fontFamily;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function createUIFont(font: Font, defaultFont: UIFont) {
|
|
||||||
var size = font.fontSize || defaultFont.pointSize;
|
|
||||||
var descriptor: UIFontDescriptor;
|
|
||||||
|
|
||||||
var symbolicTraits: number = 0;
|
|
||||||
if (font.isBold) {
|
|
||||||
symbolicTraits |= UIFontDescriptorSymbolicTraits.TraitBold;
|
|
||||||
}
|
|
||||||
if (font.isItalic) {
|
|
||||||
symbolicTraits |= UIFontDescriptorSymbolicTraits.TraitItalic;
|
|
||||||
}
|
|
||||||
|
|
||||||
descriptor = tryResolveWithSystemFont(font, size, symbolicTraits);
|
|
||||||
|
|
||||||
if (!descriptor) {
|
|
||||||
descriptor = tryResolveByFamily(font);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!descriptor) {
|
|
||||||
descriptor = utils.ios.getter(defaultFont, defaultFont.fontDescriptor).fontDescriptorWithSymbolicTraits(symbolicTraits);
|
|
||||||
}
|
|
||||||
|
|
||||||
return UIFont.fontWithDescriptorSize(descriptor, size);
|
|
||||||
}
|
|
||||||
|
|
||||||
function tryResolveWithSystemFont(font: Font, size: number, symbolicTraits: number): UIFontDescriptor {
|
|
||||||
var systemFont: UIFont;
|
|
||||||
switch (font.fontFamily) {
|
|
||||||
case common.genericFontFamilies.sansSerif:
|
|
||||||
case common.genericFontFamilies.system:
|
|
||||||
if ((<any>UIFont).systemFontOfSizeWeight) {// This method is available on iOS 8.2 and later.
|
|
||||||
systemFont = (<any>UIFont).systemFontOfSizeWeight(size, getiOSFontWeight(font.fontWeight));
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
systemFont = UIFont.systemFontOfSize(size);
|
|
||||||
}
|
|
||||||
result = utils.ios.getter(systemFont, systemFont.fontDescriptor).fontDescriptorWithSymbolicTraits(symbolicTraits);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case common.genericFontFamilies.monospace:
|
|
||||||
if ((<any>UIFont).monospacedDigitSystemFontOfSizeWeight) {// This method is available on iOS 9.0 and later.
|
|
||||||
systemFont = (<any>UIFont).monospacedDigitSystemFontOfSizeWeight(size, getiOSFontWeight(font.fontWeight));
|
|
||||||
result = utils.ios.getter(systemFont, systemFont.fontDescriptor).fontDescriptorWithSymbolicTraits(symbolicTraits);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (systemFont) {
|
|
||||||
var result = utils.ios.getter(systemFont, systemFont.fontDescriptor).fontDescriptorWithSymbolicTraits(symbolicTraits);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
function tryResolveByFamily(font: Font): UIFontDescriptor {
|
|
||||||
var fonts = common.parseFontFamily(font.fontFamily);
|
|
||||||
var result: UIFontDescriptor = null;
|
|
||||||
if (fonts.length === 0) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
ensureSystemFontSets();
|
|
||||||
|
|
||||||
for (var i = 0; i < fonts.length; i++) {
|
|
||||||
var fontFamily = getFontFamilyRespectingGenericFonts(fonts[i]);
|
|
||||||
var fontFace = getiOSFontFace(fontFamily, font.fontWeight, font.isItalic);
|
|
||||||
if (systemFonts.has(fontFamily) && !fontFace) { // This is an actual font like `HelveticaNeue-UltraLightItalic` - don't apply font face attribute
|
|
||||||
result = UIFontDescriptor.fontDescriptorWithNameSize(fontFamily, 0);
|
|
||||||
}
|
|
||||||
else if (systemFontFamilies.has(fontFamily)) { // This is a font family like `Helvetica Neue` - apply font face attribute
|
|
||||||
result = createFontDescriptor(fontFamily, fontFace);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (result) {
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
function createFontDescriptor(fontFamily: string, fontFace: string): UIFontDescriptor {
|
|
||||||
var fontAttributes = NSMutableDictionary.alloc<string, any>().init();
|
|
||||||
fontAttributes.setObjectForKey(fontFamily, "NSFontFamilyAttribute");
|
|
||||||
if (fontFace) {
|
|
||||||
fontAttributes.setObjectForKey(fontFace, "NSFontFaceAttribute");
|
|
||||||
}
|
|
||||||
return UIFontDescriptor.fontDescriptorWithFontAttributes(fontAttributes);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Available in iOS 8.2 and later.
|
|
||||||
declare var UIFontWeightThin: number; //0.8
|
|
||||||
declare var UIFontWeightUltraLight: number; //0.6
|
|
||||||
declare var UIFontWeightLight: number; //0.4
|
|
||||||
declare var UIFontWeightRegular: number; //0
|
|
||||||
declare var UIFontWeightMedium: number; //0.23
|
|
||||||
declare var UIFontWeightSemibold: number; //0.3
|
|
||||||
declare var UIFontWeightBold: number; //0.4
|
|
||||||
declare var UIFontWeightHeavy: number; //0.56
|
|
||||||
declare var UIFontWeightBlack: number; //0.62
|
|
||||||
function getiOSFontWeight(fontWeight: string): number {
|
|
||||||
if (!(<any>UIFont).systemFontOfSizeWeight) {
|
|
||||||
throw new Error("Font weight is available in iOS 8.2 and later.");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getNativeFontWeight(fontWeight: string): number {
|
||||||
switch (fontWeight) {
|
switch (fontWeight) {
|
||||||
case enums.FontWeight.thin:
|
case enums.FontWeight.thin:
|
||||||
return UIFontWeightThin;
|
|
||||||
case enums.FontWeight.extraLight:
|
|
||||||
return UIFontWeightUltraLight;
|
return UIFontWeightUltraLight;
|
||||||
|
case enums.FontWeight.extraLight:
|
||||||
|
return UIFontWeightThin;
|
||||||
case enums.FontWeight.light:
|
case enums.FontWeight.light:
|
||||||
return UIFontWeightLight;
|
return UIFontWeightLight;
|
||||||
case enums.FontWeight.normal:
|
case enums.FontWeight.normal:
|
||||||
@@ -215,76 +79,95 @@ function getiOSFontWeight(fontWeight: string): number {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function combineWeightStringWithItalic(weight: string, isItalic: boolean) {
|
function getFontFamilyRespectingGenericFonts(fontFamily: string): string {
|
||||||
if (!isItalic) {
|
if (!fontFamily) {
|
||||||
return weight;
|
return fontFamily;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!weight) {
|
switch (fontFamily.toLowerCase()) {
|
||||||
return "Italic";
|
case common.genericFontFamilies.serif:
|
||||||
}
|
return DEFAULT_SERIF;
|
||||||
|
|
||||||
return weight + " Italic";
|
case common.genericFontFamilies.monospace:
|
||||||
}
|
return DEFAULT_MONOSPACE;
|
||||||
|
|
||||||
function canLoadFont(fontFamily: string, fontFace: string) {
|
|
||||||
var trialDescriptor = createFontDescriptor(fontFamily, fontFace);
|
|
||||||
var trialFont = UIFont.fontWithDescriptorSize(trialDescriptor, 0);
|
|
||||||
return trialFont.familyName === fontFamily;
|
|
||||||
}
|
|
||||||
|
|
||||||
function findCorrectWeightString(fontFamily: string, weightStringAlternatives: Array<string>, isItalic: boolean) {
|
|
||||||
var i = 0;
|
|
||||||
let length = weightStringAlternatives.length;
|
|
||||||
for (; i < length; i++) {
|
|
||||||
var possibleFontFace = combineWeightStringWithItalic(weightStringAlternatives[i], isItalic);
|
|
||||||
if (canLoadFont(fontFamily, possibleFontFace)) {
|
|
||||||
return weightStringAlternatives[i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return weightStringAlternatives[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
function getiOSFontFace(fontFamily: string, fontWeight: string, isItalic: boolean): string {
|
|
||||||
// ... with a lot of fuzzy logic and artificial intelligence thanks to the lack of font naming standards.
|
|
||||||
var weight: string;
|
|
||||||
switch (fontWeight) {
|
|
||||||
case enums.FontWeight.thin:
|
|
||||||
weight = "Thin";
|
|
||||||
break;
|
|
||||||
case enums.FontWeight.extraLight:
|
|
||||||
weight = findCorrectWeightString(fontFamily, ["Ultra Light", "UltraLight", "Extra Light", "ExtraLight", "Ultra light", "Ultralight", "Extra light", "Extralight"], isItalic);
|
|
||||||
break;
|
|
||||||
case enums.FontWeight.light:
|
|
||||||
weight = "Light";
|
|
||||||
break;
|
|
||||||
case enums.FontWeight.normal:
|
|
||||||
case "400":
|
|
||||||
case undefined:
|
|
||||||
case null:
|
|
||||||
weight = ""; // We dont' need to write Regular
|
|
||||||
break;
|
|
||||||
case enums.FontWeight.medium:
|
|
||||||
weight = "Medium";
|
|
||||||
break;
|
|
||||||
case enums.FontWeight.semiBold:
|
|
||||||
weight = findCorrectWeightString(fontFamily, ["Demi Bold", "DemiBold", "Semi Bold", "SemiBold", "Demi bold", "Demibold", "Semi bold", "Semibold"], isItalic);
|
|
||||||
break;
|
|
||||||
case enums.FontWeight.bold:
|
|
||||||
case "700":
|
|
||||||
weight = "Bold";
|
|
||||||
break;
|
|
||||||
case enums.FontWeight.extraBold:
|
|
||||||
weight = findCorrectWeightString(fontFamily, ["Heavy", "Extra Bold", "ExtraBold", "Extra bold", "Extrabold"], isItalic);
|
|
||||||
break;
|
|
||||||
case enums.FontWeight.black:
|
|
||||||
weight = "Black";
|
|
||||||
break;
|
|
||||||
default:
|
default:
|
||||||
throw new Error(`Invalid font weight: "${fontWeight}"`);
|
return fontFamily;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return combineWeightStringWithItalic(weight, isItalic);
|
function getSystemFont(size: number, nativeWeight: number, italic: boolean, symbolicTraits: number): UIFont {
|
||||||
|
let result = UIFont.systemFontOfSizeWeight(size, nativeWeight);
|
||||||
|
if (italic) {
|
||||||
|
let descriptor = utils.ios.getter(result, result.fontDescriptor).fontDescriptorWithSymbolicTraits(symbolicTraits);
|
||||||
|
result = UIFont.fontWithDescriptorSize(descriptor, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
function createUIFont(font: Font, defaultFont: UIFont): UIFont {
|
||||||
|
let result: UIFont;
|
||||||
|
const size = font.fontSize || defaultFont.pointSize;
|
||||||
|
const nativeWeight = getNativeFontWeight(font.fontWeight);
|
||||||
|
const fontFamilies = common.parseFontFamily(font.fontFamily);
|
||||||
|
|
||||||
|
let symbolicTraits: number = 0;
|
||||||
|
if (font.isBold) {
|
||||||
|
symbolicTraits |= UIFontDescriptorSymbolicTraits.TraitBold;
|
||||||
|
}
|
||||||
|
if (font.isItalic) {
|
||||||
|
symbolicTraits |= UIFontDescriptorSymbolicTraits.TraitItalic;
|
||||||
|
}
|
||||||
|
|
||||||
|
let fontDescriptorTraits = {
|
||||||
|
[UIFontSymbolicTrait]: symbolicTraits
|
||||||
|
};
|
||||||
|
|
||||||
|
// IOS versions below 10 will not return the correct font when UIFontWeightTrait is set
|
||||||
|
// In this case - rely on UIFontSymbolicTrait only
|
||||||
|
if (SUPPORT_FONT_WEIGHTS) {
|
||||||
|
fontDescriptorTraits[UIFontWeightTrait] = nativeWeight;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (let i = 0; i < fontFamilies.length; i++) {
|
||||||
|
const fontFamily = getFontFamilyRespectingGenericFonts(fontFamilies[i]);
|
||||||
|
|
||||||
|
if (shouldUseSystemFont(fontFamily)) {
|
||||||
|
result = getSystemFont(size, nativeWeight, font.isItalic, symbolicTraits);
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
const fontAttributes = {
|
||||||
|
[UIFontDescriptorFamilyAttribute]: fontFamily,
|
||||||
|
[UIFontDescriptorTraitsAttribute]: fontDescriptorTraits
|
||||||
|
};
|
||||||
|
|
||||||
|
let descriptor = UIFontDescriptor.fontDescriptorWithFontAttributes(<any>fontAttributes);
|
||||||
|
result = UIFont.fontWithDescriptorSize(descriptor, size);
|
||||||
|
|
||||||
|
let actualItalic = utils.ios.getter(result, result.fontDescriptor).symbolicTraits & UIFontDescriptorSymbolicTraits.TraitItalic;
|
||||||
|
if (font.isItalic && !actualItalic && EMULATE_OBLIQUE) {
|
||||||
|
// The font we got is not actually italic so emulate that with a matrix
|
||||||
|
descriptor = descriptor.fontDescriptorWithMatrix(OBLIQUE_TRANSFORM);
|
||||||
|
result = UIFont.fontWithDescriptorSize(descriptor, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if the resolved font has the correct font-family
|
||||||
|
// If not - fallback to the next font-family
|
||||||
|
if (result.familyName === fontFamily) {
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
result = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Couldn't resolve font - fallback to the system font
|
||||||
|
if (!result) {
|
||||||
|
result = getSystemFont(size, nativeWeight, font.isItalic, symbolicTraits);
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
export module ios {
|
export module ios {
|
||||||
@@ -312,8 +195,6 @@ export module ios {
|
|||||||
trace.write("Error occur while registering font: " + CFErrorCopyDescription(<NSError>error.value), trace.categories.Error, trace.messageType.error);
|
trace.write("Error occur while registering font: " + CFErrorCopyDescription(<NSError>error.value), trace.categories.Error, trace.messageType.error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
areSystemFontSetsValid = false;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user