opentype.features.js
Version:
Library to list opentype fonts optional features.
178 lines (177 loc) • 6.92 kB
JavaScript
"use strict";
// The Font object
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
var position_1 = __importDefault(require("./position"));
var substitution_1 = __importDefault(require("./substitution"));
var util_1 = require("./util");
/**
* @typedef FontOptions
* @type Object
* @property {Boolean} empty - whether to create a new empty font
* @property {string} familyName
* @property {string} styleName
* @property {string=} fullName
* @property {string=} postScriptName
* @property {string=} designer
* @property {string=} designerURL
* @property {string=} manufacturer
* @property {string=} manufacturerURL
* @property {string=} license
* @property {string=} licenseURL
* @property {string=} version
* @property {string=} description
* @property {string=} copyright
* @property {string=} trademark
* @property {Number} unitsPerEm
* @property {Number} ascender
* @property {Number} descender
* @property {Number} createdTimestamp
* @property {string=} weightClass
* @property {string=} widthClass
* @property {string=} fsSelection
*/
/**
* A Font represents a loaded OpenType font file.
* It contains a set of glyphs and methods to draw text on a drawing context,
* or to get a path representing the text.
* @exports opentype.Font
* @class
* @param {FontOptions}
* @constructor
*/
function Font(options) {
options = options || {};
options.tables = options.tables || {};
if (!options.empty) {
// Check that we've provided the minimum set of names.
(0, util_1.checkArgument)(options.familyName, 'When creating a new Font object, familyName is required.');
(0, util_1.checkArgument)(options.styleName, 'When creating a new Font object, styleName is required.');
(0, util_1.checkArgument)(options.unitsPerEm, 'When creating a new Font object, unitsPerEm is required.');
(0, util_1.checkArgument)(options.ascender, 'When creating a new Font object, ascender is required.');
(0, util_1.checkArgument)(options.descender <= 0, 'When creating a new Font object, negative descender value is required.');
// OS X will complain if the names are empty, so we put a single space everywhere by default.
this.names = {
fontFamily: { en: options.familyName || ' ' },
fontSubfamily: { en: options.styleName || ' ' },
fullName: { en: options.fullName || options.familyName + ' ' + options.styleName },
// postScriptName may not contain any whitespace
postScriptName: { en: options.postScriptName || (options.familyName + options.styleName).replace(/\s/g, '') },
designer: { en: options.designer || ' ' },
designerURL: { en: options.designerURL || ' ' },
manufacturer: { en: options.manufacturer || ' ' },
manufacturerURL: { en: options.manufacturerURL || ' ' },
license: { en: options.license || ' ' },
licenseURL: { en: options.licenseURL || ' ' },
version: { en: options.version || 'Version 0.1' },
description: { en: options.description || ' ' },
copyright: { en: options.copyright || ' ' },
trademark: { en: options.trademark || ' ' }
};
this.unitsPerEm = options.unitsPerEm || 1000;
this.ascender = options.ascender;
this.descender = options.descender;
this.createdTimestamp = options.createdTimestamp;
this.tables = Object.assign(options.tables, {
os2: Object.assign({
usWeightClass: options.weightClass || this.usWeightClasses.MEDIUM,
usWidthClass: options.widthClass || this.usWidthClasses.MEDIUM,
fsSelection: options.fsSelection || this.fsSelectionValues.REGULAR,
}, options.tables.os2)
});
}
this.supported = true; // Deprecated: parseBuffer will throw an error if font is not supported.
this.position = new position_1.default(this);
this.substitution = new substitution_1.default(this);
this.tables = this.tables || {};
// needed for low memory mode only.
this._push = null;
this._hmtxTableData = {};
Object.defineProperty(this, 'hinting', {
get: function () {
if (this._hinting)
return this._hinting;
if (this.outlinesFormat === 'truetype') {
return (this._hinting = new HintingTrueType(this));
}
}
});
}
/**
* @typedef GlyphRenderOptions
* @type Object
* @property {string} [script] - script used to determine which features to apply. By default, 'DFLT' or 'latn' is used.
* See https://www.microsoft.com/typography/otspec/scripttags.htm
* @property {string} [language='dflt'] - language system used to determine which features to apply.
* See https://www.microsoft.com/typography/developers/opentype/languagetags.aspx
* @property {boolean} [kerning=true] - whether to include kerning values
* @property {object} [features] - OpenType Layout feature tags. Used to enable or disable the features of the given script/language system.
* See https://www.microsoft.com/typography/otspec/featuretags.htm
*/
Font.prototype.defaultRenderOptions = {
kerning: true,
features: [
/**
* these 4 features are required to render Arabic text properly
* and shouldn't be turned off when rendering arabic text.
*/
{ script: 'arab', tags: ['init', 'medi', 'fina', 'rlig'] },
{ script: 'latn', tags: ['liga', 'rlig'] }
]
};
/**
* @param {string}
* @return {string}
*/
Font.prototype.getEnglishName = function (name) {
var translations = this.names[name];
if (translations) {
return translations.en;
}
};
/**
* @private
*/
Font.prototype.fsSelectionValues = {
ITALIC: 0x001,
UNDERSCORE: 0x002,
NEGATIVE: 0x004,
OUTLINED: 0x008,
STRIKEOUT: 0x010,
BOLD: 0x020,
REGULAR: 0x040,
USER_TYPO_METRICS: 0x080,
WWS: 0x100,
OBLIQUE: 0x200 //512
};
/**
* @private
*/
Font.prototype.usWidthClasses = {
ULTRA_CONDENSED: 1,
EXTRA_CONDENSED: 2,
CONDENSED: 3,
SEMI_CONDENSED: 4,
MEDIUM: 5,
SEMI_EXPANDED: 6,
EXPANDED: 7,
EXTRA_EXPANDED: 8,
ULTRA_EXPANDED: 9
};
/**
* @private
*/
Font.prototype.usWeightClasses = {
THIN: 100,
EXTRA_LIGHT: 200,
LIGHT: 300,
NORMAL: 400,
MEDIUM: 500,
SEMI_BOLD: 600,
BOLD: 700,
EXTRA_BOLD: 800,
BLACK: 900
};
exports.default = Font;