Skip to content

Instantly share code, notes, and snippets.

@drbr
Created August 15, 2024 00:11
Show Gist options
  • Save drbr/0344ca58680f50ec317e23ca770da0db to your computer and use it in GitHub Desktop.
Save drbr/0344ca58680f50ec317e23ca770da0db to your computer and use it in GitHub Desktop.
Render text in a font as SVG
#!/usr/bin/env node
const { program } = require('commander');
const opentype = require('opentype.js');
const fs = require('fs');
program
.name('svgFromFont')
.usage("'text' [options]")
.description(
'Renders the given text using a specified font and outputs it as an SVG, which can be used as an image on the web.'
)
.argument('<text>', 'the text to render')
.requiredOption('-f, --font <path>', 'path to the font to use for rendering')
.option('-s, --size <number>', 'font size to render at', 72)
.showHelpAfterError();
program.parse();
const [TEXT_TO_RENDER] = program.args;
const { font: FONT_PATH, size: SIZE } = program.opts();
// Sometimes the edges get clipped for an unknown reason, so add 1 unit of padding on all sides
const PADDING = 1;
const file = fs.readFileSync(FONT_PATH);
const font = opentype.parse(file.buffer);
const pathObject = font.getPath(TEXT_TO_RENDER, 0, 0, SIZE);
const pathData = pathObject.toPathData({ flipY: true });
const boundingBox = pathObject.getBoundingBox();
const left = boundingBox.x1 - PADDING;
const top = boundingBox.y1 - PADDING;
const width = boundingBox.x2 - boundingBox.x1 + 2 * PADDING;
const height = boundingBox.y2 - boundingBox.y1 + 2 * PADDING;
const viewBoxString = `${left} ${top} ${width} ${height}`;
const svgText = `<svg height="100%" viewBox="${viewBoxString}" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="${pathData}" fill="currentColor"/></svg>`;
console.log(svgText);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment