// Shared helpers for the logo scripts: rasterise a Canva PDF page with pdf.js and @napi-rs/canvas. import { readFileSync } from "node:fs"; import path from "node:path"; import { fileURLToPath } from "node:url"; export const ROOT = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "../.."); export const PDF_DIR = path.join(ROOT, "templates", "Modern Neutral Invoice Template"); export const SCALE = 4; export const PAGE = { w: 595.5, h: 842.25 }; export const OUT_DIR = "/tmp/invoice-c2"; export async function loadCanvas() { try { return await import("@napi-rs/canvas"); } catch { console.error("@napi-rs/canvas is not installed (it is an optional dev dependency); run npm install"); process.exit(1); } } /** Renders page 1 of the Canva PDF `n` at SCALE x. Returns the canvas. */ export async function renderPage(n, scale = SCALE) { const { createCanvas } = await loadCanvas(); const pdfjs = await import("pdfjs-dist/legacy/build/pdf.mjs"); const data = new Uint8Array(readFileSync(path.join(PDF_DIR, `${n}.pdf`))); const doc = await pdfjs.getDocument({ data, isEvalSupported: false, verbosity: 0 }).promise; const page = await doc.getPage(1); const vp = page.getViewport({ scale }); const canvas = createCanvas(Math.round(vp.width), Math.round(vp.height)); await page.render({ canvasContext: canvas.getContext("2d"), viewport: vp, canvas }).promise; return canvas; } /** Copies a pt rectangle of a page canvas into a new canvas (same scale). */ export async function cropCanvas(canvas, rect, scale = SCALE) { const { createCanvas } = await loadCanvas(); const x = Math.round(rect.x * scale); const y = Math.round(rect.y * scale); const w = Math.round(rect.w * scale); const h = Math.round(rect.h * scale); const out = createCanvas(w, h); out.getContext("2d").drawImage(canvas, x, y, w, h, 0, 0, w, h); return out; } /** Canva PDF number of each template (docs/templates/README.md). */ export const TEMPLATE_PDF = { marble: 1, highlighter: 2, monolith: 3, linea: 4, monogram: 5, serenity: 6, "crimson-grid": 7, "cobalt-stripe": 8, "slate-band": 9, "teal-swoosh": 10, "tangerine-ledger": 11, "purple-pop": 12, "citrus-split": 13, };