astro-ghostcms/.pnpm-store/v3/files/ce/71f8d8276f0e91a19dc507599bb...

97 lines
3.5 KiB
JavaScript
Executable File

#!/usr/bin/env node
// This is a command to test the text rendering compliance of OpenType.js.
// It is designed to operate with https://github.com/unicode-org/text-rendering-tests.
//
// Call it like this:
//
// ./bin/test-render --font=fonts/FiraSansOT-Medium.otf --testcase=TEST-1 --render=BALL
//
// The output will look like this:
//
// <?xml version="1.0" encoding="UTF-8"?>
// <svg version="1.1"
// xmlns="http://www.w3.org/2000/svg"
// xmlns:xlink="http://www.w3.org/1999/xlink"
// viewBox="0 -500 2230 1550">
// <symbol id="TEST-1.B" overflow="visible"><path d="M443 203C443 117 375 99 309 99L217 99L217 315L315 315C389 315 443 289 443 203ZM417 504C417 436 380 407 305 407L217 407L217 594L299 594C375 594 417 568 417 504ZM581 200C581 312 500 352 432 365L432 369C489 382 552 430 552 515C552 651 429 691 295 691L84 691L84 0L307 0C448 0 581 44 581 200Z"/></symbol>
// <symbol id="TEST-1.A" overflow="visible"><path d="M452 0L594 0L377 691L214 691L-5 0L133 0L177 160L408 160ZM291 581L295 581L383 260L202 260Z"/></symbol>
// <symbol id="TEST-1.L" overflow="visible"><path d="M478 0L493 108L217 108L217 691L84 691L84 0Z"/></symbol>
// <use xlink:href="#TEST-1.B" x="0" y="0"/>
// <use xlink:href="#TEST-1.A" x="625" y="0"/>
// <use xlink:href="#TEST-1.L" x="1214" y="0"/>
// <use xlink:href="#TEST-1.L" x="1722" y="0"/>
// </svg>
//
// When viewing the SVG, it will be upside-down (since glyphs are designed Y-up).
var opentype = require('../dist/opentype.js');
const SVG_FOOTER = `</svg>`;
function printUsage() {
console.log('Usage: test-render --font=filename.otf --testcase=TEST_NAME --render=TEXT_TO_RENDER');
console.log('This commands output the text to render as an SVG file.');
console.log();
}
let filename;
let testcase;
let textToRender;
for (let i = 0; i < process.argv.length; i++) {
const arg = process.argv[i];
if (arg.startsWith('--font=')) {
filename = arg.substring('--font='.length);
} else if (arg.startsWith('--testcase=')) {
testcase = arg.substring('--testcase='.length);
} else if (arg.startsWith('--render=')) {
textToRender = arg.substring('--render='.length);
}
}
if (filename === undefined || testcase === undefined || textToRender === undefined) {
printUsage();
process.exit(1);
}
function renderSVG() {
var font = opentype.loadSync(filename);
let svgSymbols = [];
let svgBody = [];
var glyphSet = new Set();
let x = 0;
const glyphs = font.stringToGlyphs(textToRender);
for (let i = 0; i < glyphs.length; i++) {
const glyph = glyphs[i];
const symbolId = testcase + '.' + glyph.name;
if (!glyphSet.has(glyph)) {
glyphSet.add(glyph);
const svgPath = glyph.path.toSVG();
svgSymbols.push(` <symbol id="${symbolId}" overflow="visible">${svgPath}</symbol>`);
}
svgBody.push(` <use xlink:href="#${symbolId}" x="${x}" y="0"/>`);
x += glyph.advanceWidth;
}
let minX = 0;
let minY = Math.round(font.descender);
let width = Math.round(x);
let height = Math.round(font.ascender - font.descender);
let svgHeader = `<?xml version="1.0" encoding="UTF-8"?>
<svg version="1.1"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
viewBox="${minX} ${minY} ${width} ${height}">`;
return svgHeader + svgSymbols.join('\n') + svgBody.join('\n') + SVG_FOOTER;
}
try {
var svg = renderSVG();
console.log(svg);
} catch(e) {
console.error(e.stack);
process.exit(1);
}