This is the Node.js adapter of [python font tools](https://github.com/fonttools/fonttools) via [Pyodide](https://pyodide.org) without having to install python and its dependencies.
npm install @web-alchemy/fonttoolsThis is the Node.js adapter of python font tools via Pyodide without having to install python and its dependencies.
Font tools library usually used for optimizing fonts – subseting, format converting, deleting of unused variable font axes, etc.
You can install the library as a global dependency:
``shell`
npm install --global @web-alchemy/fonttools
After installing font utilities will be available globally:
`shell`
fonttools
pyftsubset
pyftmerge
ttx
Also you can use this tool via npx:
`shell`
npx -p @web-alchemy/fonttools
npx -p @web-alchemy/fonttools pyftsubset
npx -p @web-alchemy/fonttools pyftmerge
npx -p @web-alchemy/fonttools ttx
Example of converting ttf to woff2:
`shell`
npx -p @web-alchemy/fonttools pyftsubset \
"./some/path/to/font.ttf" \
"*" \ # keep all glyphs and just convert format
--output-file="./some/path/to/font.woff2" \
--flavor="woff2"
Example of converting ttf to woff2 and subseting with text and unicodes options:
`shell`
npx -p @web-alchemy/fonttools pyftsubset \
"./some/path/to/font.ttf" \
--output-file="./some/path/to/font.woff2" \
--flavor="woff2" \
--text="The text whose characters will be included in the font file" \
--unicodes="U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD" \
--desubroutinize \
--no-hinting \
--layout-features="*"
Example of customizing variable font's axes:
`shellwght
npx @web-alchemy/fonttools varLib.instancer \
"./src/font.woff2" \
# decrease axis rangewdth
wght=400:600 \
# delete axis`
wdth=drop \
--output="./dist/font.woff2"
Library provides few JavaScript specific methods:
`javascript`
const {
subset,
instantiateVariableFont,
ttx
} = require('@web-alchemy/fonttools')
Example of converting ttf to woff2:
`javascript
const fs = require('node:fs')
const { subset } = require('@web-alchemy/fonttools')
async function main() {
const inputFileBuffer = await fs.promises.readFile('./font.ttf')
const outputFileBuffer = await subset(inputFileBuffer, {
'*': true, // keep all glyphs and just convert format
'flavor': 'woff2',
})
await fs.promises.writeFile('./font.woff2', outputFileBuffer)
}
main()
`
Example of converting ttf to woff2 and subseting with text and unicodes options:
`javascript
const fs = require('node:fs')
const { subset } = require('@web-alchemy/fonttools')
async function main() {
const inputFileBuffer = await fs.promises.readFile('./font.ttf')
const outputFileBuffer = await subset(inputFileBuffer, {
'text': "The text whose characters will be included in the font file",
'unicodes': "U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD",
'flavor': 'woff2',
})
await fs.promises.writeFile('./font.woff2', outputFileBuffer)
}
main()
`
Method subset takes same params as original pyftsubset utility(without dashes --).
Example of customizing variable font's axes:
`javascript
const fs = require('node:fs')
const { instantiateVariableFont } = require('@web-alchemy/fonttools')
async function main() {
const inputFileBuffer = await fs.promises.readFile('./src/font.woff2')
const outputFileBuffer = await instantiateVariableFont(inputFileBuffer, {
wght: [300, 500], // decrease wght axis rangewdth
wdth: null // delete axis
})
await fs.promises.writeFile('dist/font.woff2', outputFileBuffer)
}
main()
`
This is port of method varLib.instancer.instantiateVariableFont.
Method ttx can convert binary font files (.otf, .ttf, etc) to the TTX XML format and convert them back to binary format.
Example of converting binary files to xml:
`javascript
const fs = require('node:fs');
const { ttx } = require('@web-alchemy/fonttools');
(async () => {
const outputTtxBuffer = await ttx('./font.ttf'); // also accept URL and Buffer`
await fs.promises.writeFile('./font.ttx', outputTtxBuffer);
const outputOtxBuffer = await ttx('./font.otf');
await fs.promises.writeFile('./font.otx', outputOtxBuffer);
})();
Example of converting xml files to binary files:
`javascript
const fs = require('node:fs');
const { ttx } = require('@web-alchemy/fonttools');
(async () => {
const ttfBuffer = await ttx('./font.ttx');
await fs.promises.writeFile('./font.ttf', ttfBuffer);
const otfBuffer = await ttx('./font.otx');
await fs.promises.writeFile('./font.otf', otfBuffer);
})();
`
Example of converting xml files to binary files with encoding to woff2:
`javascript
const fs = require('node:fs');
const { ttx } = require('@web-alchemy/fonttools');
(async () => {
const ttfBuffer = await ttx('./font.ttx', [
['--flavor', 'woff2']
]);
await fs.promises.writeFile('./font.woff2', ttfBuffer);
const otfBuffer = await ttx('./font.otx', [
['--flavor', 'woff2']
]);
await fs.promises.writeFile('./font.woff2', otfBuffer);
})();
`
- Doesn't support zopfli package for better optimizing woff files.
- In CLI all file paths should be relative to cwd` (current working directory).