import enums = require("ui/enums"); import common = require("./font-common"); import fs = require("file-system"); import * as traceModule from "trace"; var DEFAULT_SERIF = "Times New Roman"; var DEFAULT_SANS_SERIF = "Helvetica"; var DEFAULT_MONOSPACE = "Courier New"; export class Font extends common.Font { public static default = new Font(undefined, undefined, enums.FontStyle.normal, enums.FontWeight.normal); private _uiFont: UIFont; constructor(family: string, size: number, style: string, weight: string) { super(family, size, style, weight); } public getUIFont(defaultFont: UIFont): UIFont { if (!this._uiFont) { var symbolicTraits: number = 0; if (this.isBold) { symbolicTraits |= UIFontDescriptorSymbolicTraits.UIFontDescriptorTraitBold; } if (this.isItalic) { symbolicTraits |= UIFontDescriptorSymbolicTraits.UIFontDescriptorTraitItalic; } var descriptor = resolveFontDescriptor(this.fontFamily, symbolicTraits); if (!descriptor) { descriptor = defaultFont.fontDescriptor().fontDescriptorWithSymbolicTraits(symbolicTraits); } var size = this.fontSize || defaultFont.pointSize; this._uiFont = UIFont.fontWithDescriptorSize(descriptor, size); } return this._uiFont; } public withFontFamily(family: string): Font { return new Font(family, this.fontSize, this.fontStyle, this.fontWeight); } public withFontStyle(style: string): Font { return new Font(this.fontFamily, this.fontSize, style, this.fontWeight); } public withFontWeight(weight: string): 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); } } var areSystemFontSetsValid: boolean = false; var systemFontFamilies = new Set(); var systemFonts = new Set(); function assureSystemFontSets() { if (!areSystemFontSetsValid) { 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); } } areSystemFontSetsValid = true; } } function resolveFontDescriptor(fontFamilyValue: string, symbolicTraits: number): UIFontDescriptor { var fonts = common.parseFontFamily(fontFamilyValue); var result: UIFontDescriptor = null; if (fonts.length === 0) { return null; } assureSystemFontSets(); for (var i = 0; i < fonts.length; i++) { var fontFamily = getFontFamilyRespectingGenericFonts(fonts[i]); if (systemFonts.has(fontFamily)) { // This is an actual font - don't apply symbolic traits result = UIFontDescriptor.fontDescriptorWithNameSize(fontFamily, 0); } else if (systemFontFamilies.has(fontFamily)) { // This is a font family - we should apply symbolic traits if there are such var fontFaceAttributes = []; if (!symbolicTraits) { fontFaceAttributes.push("Regular"); } else { if (symbolicTraits & UIFontDescriptorSymbolicTraits.UIFontDescriptorTraitBold) { fontFaceAttributes.push("Bold"); } if (symbolicTraits & UIFontDescriptorSymbolicTraits.UIFontDescriptorTraitItalic) { fontFaceAttributes.push("Italic"); } } var fontAttributes = NSMutableDictionary.alloc().init(); fontAttributes.setObjectForKey(fontFamily, "NSFontFamilyAttribute"); fontAttributes.setObjectForKey(fontFaceAttributes.join(" "), "NSFontFaceAttribute"); result = UIFontDescriptor.fontDescriptorWithFontAttributes(fontAttributes); } 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; } } export module ios { export function registerFont(fontFile: string) { var filePath = fs.path.join(fs.knownFolders.currentApp().path, "fonts", fontFile); if (!fs.File.exists(filePath)) { filePath = fs.path.join(fs.knownFolders.currentApp().path, fontFile); } var fontData = NSFileManager.defaultManager().contentsAtPath(filePath); if (!fontData) { throw new Error("Could not load font from: " + fontFile); } var provider = CGDataProviderCreateWithCFData(fontData); var font = CGFontCreateWithDataProvider(provider); if (!font) { throw new Error("Could not load font from: " + fontFile); } var error = new interop.Reference(); if (!CTFontManagerRegisterGraphicsFont(font, error)) { var trace: typeof traceModule = require("trace"); trace.write("Error occur while registering font: " + CFErrorCopyDescription(error.value), trace.categories.Error, trace.messageType.error); } areSystemFontSetsValid = false; } } function registerCustomFonts() { var fontsFolderPath = fs.path.join(__dirname.substring(0, __dirname.indexOf("/tns_modules")), "fonts"); if (fs.Folder.exists(fontsFolderPath)) { var fontsFolder = fs.Folder.fromPath(fontsFolderPath); var onEachEntityFunc = function (fileEntity: fs.FileSystemEntity): boolean { if (fs.Folder.exists(fs.path.join(fontsFolderPath, fileEntity.name))) { return true; } if (fileEntity instanceof fs.File && ((fileEntity).extension === ".ttf" || (fileEntity).extension === ".otf")) { ios.registerFont(fileEntity.name); } return true; } fontsFolder.eachEntity(onEachEntityFunc); } } registerCustomFonts();