/ src / elements / pdf.ts
pdf.ts
 1  import type { PDFFont } from "@cantoo/pdf-lib";
 2  import type { Page } from "./page";
 3  import type { MemoryFont } from "~/utils/fonts";
 4  import { PDFDocument } from "@cantoo/pdf-lib";
 5  
 6  export class PDF {
 7    private _author?: string;
 8    private _children: Array<Page> = [];
 9    private _fonts: Set<MemoryFont> = new Set();
10    private _javascripts: Map<string, string> = new Map();
11  
12    /**
13     * Set this document's author metadata. The author will appear in the
14     * "Document Properties" section of most PDF readers.
15     *
16     * @param author The author of this document.
17     */
18    author(author: string): PDF {
19      this._author = author;
20      return this;
21    }
22  
23    child(page: Page): PDF {
24      this._children.push(page);
25      return this;
26    }
27  
28    font(font: MemoryFont): PDF {
29      this._fonts.add(font);
30      return this;
31    }
32  
33    async renderToBytes(): Promise<Uint8Array> {
34      const pdf = await PDFDocument.create();
35  
36      // Embed all the fonts we need for usage within the PDF.
37      const fonts = new Map<MemoryFont, PDFFont>();
38      if (this._fonts.size > 0) {
39        await Promise.all(
40          this._fonts.values().map(async (memory) => {
41            const font = await pdf.embedFont(memory.value);
42            fonts.set(memory, font);
43          })
44        );
45      }
46  
47      if (this._author) pdf.setAuthor(this._author);
48  
49      if (this._javascripts.size > 0) {
50        for (const [name, script] of this._javascripts.entries()) {
51          pdf.addJavaScript(name, script);
52        }
53      }
54  
55      for (const child of this._children) {
56        const page = pdf.addPage();
57        console.log("-- rendering page");
58        child.render(page, fonts);
59      }
60  
61      return pdf.save();
62    }
63  
64    script(name: string, script: string): PDF {
65      this._javascripts.set(name, script);
66      return this;
67    }
68  }
69  export const pdf = (): PDF => new PDF();