OpenType.Features.js
Library to list opentype fonts optional features
Font table reading code from opentype.js
Installation
npm install --save opentype.features.js
This assumes you are using npm as your package manager.
Works with ttf, woff and woff2 fonts.
Doesn't currently support woff2 font collections. ('ttcf')
Usage
// Example : running on node.
import Features from 'opentype.features.js';
const f = async () =>
{
let features = await Features.getFeaturesFromFile('C:\\Windows\\Fonts\\CharisSIL-R.ttf');
console.log(JSON.stringify(features));
}
f();
// Example : running in browser
import Features from 'opentype.features.js';
Features.getFeaturesFromUrl("http://localhost:3000/Andika-Regular.ttf").then((value) => {
console.log(JSON.stringify(value));
});
// Example Outputs
[{"tag":"cv13","description":"Cap B-hook alt","options":["Lowercase style"],"alternateCharacters":["Ɓ"]},{"tag":"cv17","description":"Cap D-hook alt","options":["Lowercase style"],"alternateCharacters":["Ɗ"]},{"tag":"cv19","description":"Sm ezh-curl alt","options":["Large bowl"],"alternateCharacters":["ʓ"]},{"tag":"cv20","description":"Cap Ezh alts","options":["Reversed sigma"],"alternateCharacters":["Ʒ","Ӡ"]},{"tag":"cv25","description":"Rams horn alts","options":["Large Bowl","Small gamma"],"alternateCharacters":["ɤ"]},{"tag":"cv28","description":"Cap H-stroke alt","options":["Vertical-stroke"],"alternateCharacters":["Ħ"]},{"tag":"cv37","description":"J-strok alt","options":["Top serif"],"alternateCharacters":["ʄ"]},{"tag":"cv43","description":"Uppercase Eng alts","options":["Large eng on baseline","Capital N with tail","Large eng with short stem"],"alternateCharacters":["Ŋ"]},{"tag":"cv44","description":"Cap N-left-hook alt","options":["Lowercase style"],"alternateCharacters":["Ɲ"]},{"tag":"cv46","description":"Open-O alts","options":["Top serif"],"alternateCharacters":["ɔ","ᵓ","ᶗ","Ɔ","ᴐ"]},{"tag":"cv47","description":"OU alts","options":["Open"],"alternateCharacters":["ȣ","Ȣ","ᴽ","ᴕ"]},{"tag":"cv49","description":"Sm p-hook alt","options":["Right hook"],"alternateCharacters":["ƥ"]},{"tag":"cv55","description":"Cap R-tail alt","options":["Lowercase style"],"alternateCharacters":["Ɽ"]},{"tag":"cv57","description":"Cap T-hook alt","options":["Right Hook"],"alternateCharacters":["Ƭ"]},{"tag":"cv62","description":"V-hook alts","options":["Straight with low hook","Straight with high hook"],"alternateCharacters":["ʋ","ᶹ","Ʋ"]},{"tag":"cv68","description":"Cap Y-hook alt","options":["Left hook"],"alternateCharacters":["Ƴ"]},{"tag":"cv70","description":"Mod apostrophe alt","options":["Large"],"alternateCharacters":["Ꞌ","ꞌ","ʼ"]},{"tag":"cv71","description":"Mod colon alt","options":["Expanded"],"alternateCharacters":["꞉"]},{"tag":"cv75","description":"Viet diacritics","options":["Vietnamese-style"],"alternateCharacters":[]},{"tag":"cv76","description":"Ogonek alt","options":["Straight"],"alternateCharacters":["˛","ą","Ą","ę","Ę","į","Į","ǫ","ǭ","Ǫ","Ǭ","ų","Ų","̨"]},{"tag":"cv77","description":"Non-Eur caron alts","options":["Non-European style"],"alternateCharacters":["ď","ľ","Ľ","ť"]},{"tag":"cv80","description":"Mongol-style Cyr E","options":["Mongolian-style"],"alternateCharacters":["э","Э"]},{"tag":"cv81","description":"Cyr shha alt","options":["Uppercase style"],"alternateCharacters":["һ"]},{"tag":"cv82","description":"Breve Cyr form","options":["Cyrillic-style"],"alternateCharacters":["̆"]},{"tag":"cv90","description":"Chinantec tones","options":["Chinantec-style"],"alternateCharacters":["ˈ","ˊ","ˋ","ˉ"]},{"tag":"cv91","description":"Tone numbers","options":["Numbers"]},{"tag":"cv98","description":"Empty set alt","options":["Zero"],"alternateCharacters":["∅"]},{"tag":"ss01","description":"Style Set 1","options":[],"alternateCharacters":[],"type":16},{"tag":"ss04","description":"Style Set 4","options":[],"alternateCharacters":[],"type":16},{"tag":"ss05","description":"Style Set 5","options":[],"alternateCharacters":[],"type":16},{"tag":"ss06","description":"Style Set 6","options":[],"alternateCharacters":[],"type":16}]
// Example : typescript
import Features, {Feature} from 'opentype.features.js';
const f = async () =>
{
let features: Feature[] = await Features.getFeaturesFromFile('C:\\Windows\\Fonts\\CharisSIL-R.ttf');
return this.state.features.map((f: Feature) => f.description);
}
f();
// Example : Using local fonts (Chrome 103+)
const f = async () =>
{
// Assuming - local-font permission already granted.
// await navigator.permissions.request({
// name: 'local-fonts',
// }
const pickedFonts = await window.queryLocalFonts({
postscriptNames: ['CharisSIL'],
});
const fontData = pickedFonts[0];
let blob = await fontData.blob();
let buffer = await blob.arrayBuffer();
const features = await Features.getFeaturesFromArrayBuffer(buffer.buffer);
console.log(JSON.stringify(features));
}
f();
Feature Module
getFeaturesFromFile(filename : string)
Node ONLY
-
filename
- supported font file.
returns Feature[]
getFeaturesFromUrl(url : string)
Browser or Node
-
url
- url to supported font file.
returns Feature[]
getFeaturesFromArrayBuffer(buffer : ArrayBuffer)
-
buffer
- binary data of supported font file.
returns Feature[]
interface Feature
{
tag: string;
description: string;
options: string[];
// unicode characters that this feature modifies.
alternateCharacters: string[]
type?: FeatureType;
}
Font Module
getMetaDataFromFile(filename)
-
filename
{string}
- ttf or woff file.
returns MetaData
getMetaDataFromUrl(url)
-
url
{string}
- url to ttf or woff file.
returns MetaData
interface MetaData
{
fontFamily: string;
}
Troubleshooting
- Failing to import 'fs' via
brotli
dependency.
If you are using a bundle builder like webpack
it is likely configured to exclude 'fs' polyfills.
Install path-browserify
(or something equivalent) to provide 'fs'.
The brotli
dependency is needed for WOFF2 support.