// Rasterise the Software Design figures (scripts/sdlc-seed/figures.mjs) to PNG with the // document font, so Thai labels print the same in the PDF and survive the Word conversion. // Usage: node scripts/sdlc-delivery/render-figures.mjs import fs from 'node:fs/promises'; import path from 'node:path'; import { fileURLToPath } from 'node:url'; import { chromium } from 'playwright'; import { FIGURES } from '../sdlc-seed/figures.mjs'; const here = path.dirname(fileURLToPath(import.meta.url)); const output = path.resolve(here, '../sdlc-seed/figures'); async function main() { const font = await fs.readFile(path.join(here, 'assets/LeelawadeeUI.ttf')); const fontFace = `@font-face { font-family: "BRN Thai"; src: url(data:font/ttf;base64,${font.toString('base64')}) format("truetype"); font-weight: 400 700; }`; await fs.mkdir(output, { recursive: true }); const browser = await chromium.launch({ headless: true }); try { const page = await (await browser.newContext({ deviceScaleFactor: 2 })).newPage(); for (const [file, , draw] of Object.values(FIGURES)) { const svg = draw(); const [, w, h] = svg.match(/width="(\d+)" height="(\d+)"/); await page.setViewportSize({ width: Number(w), height: Number(h) }); await page.setContent(`
${svg}`); await page.evaluate(() => document.fonts.ready); await page.locator('svg').first().screenshot({ path: path.join(output, `${file}.png`) }); console.log(`Rendered figures/${file}.png`); } } finally { await browser.close(); } } main().catch((error) => { console.error(error); process.exit(1); });