podpdf 1.0.1 → 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,49 +1,57 @@
1
1
  # podpdf
2
2
 
3
- **Ultra-fast, zero-dependency PDF generation for Node.js & Bun**
3
+ **Ultra-fast, zero-dependency PDF generation for Node.js, Bun & Browser**
4
4
 
5
5
  [![npm version](https://img.shields.io/npm/v/podpdf.svg)](https://www.npmjs.com/package/podpdf)
6
6
  [![bundle size](https://img.shields.io/badge/size-8KB-brightgreen)](https://bundlephobia.com/package/podpdf)
7
7
  [![zero dependencies](https://img.shields.io/badge/dependencies-0-blue)](https://www.npmjs.com/package/podpdf)
8
+ [![Buy Me A Coffee](https://img.shields.io/badge/Buy%20Me%20A%20Coffee-Support-yellow?logo=buy-me-a-coffee)](https://buymeacoffee.com/herostack)
8
9
 
9
10
  ```
10
- 8 KB minified • Zero dependencies • 5x faster than jsPDF • TypeScript native
11
+ ~9 KB minified • Zero dependencies • 5x faster than jsPDF • TypeScript native
11
12
  ```
12
13
 
13
14
  ## Why podpdf?
14
15
 
15
- | Library | Size | Dependencies | Speed |
16
- |---------|------|--------------|-------|
17
- | **podpdf** | **8 KB** | **0** | **5.5x** |
18
- | jsPDF | 290 KB | 2+ | 1x |
19
- | pdfkit | 1 MB | 10+ | 0.8x |
16
+ | Library | Size | Dependencies | Speed | Environment |
17
+ |---------|------|--------------|-------|-------------|
18
+ | **podpdf** | **~9 KB** | **0** | **5.5x** | Node.js/Bun |
19
+ | **podpdf/plus** | **~13 KB** | **0** | **5x** | Node.js/Bun |
20
+ | **podpdf/browser** | **~9 KB** | **0** | **5.5x** | **Browser** ✨ |
21
+ | jsPDF | 290 KB | 2+ | 1x | Browser/Node |
22
+ | pdfkit | 1 MB | 10+ | 0.8x | Node.js only |
20
23
 
21
24
  ## Feature Comparison
22
25
 
23
- | Feature | podpdf | jsPDF | pdfkit |
24
- |---------|:------:|:-----:|:------:|
25
- | **Text** | | | |
26
- | **Text Styling (bold/italic)** | ✅ | ✅ | ✅ |
27
- | **Text Wrap** | ✅ | ✅ | ✅ |
28
- | **Text Alignment** | ✅ | ✅ | ✅ |
29
- | **Rectangle** | ✅ | ✅ | ✅ |
30
- | **Rounded Rectangle** | ✅ | ✅ | ✅ |
31
- | **Circle** | ✅ | ✅ | ✅ |
32
- | **Line (solid/dashed)** | | ✅ | |
33
- | **Tables** | ✅ | ⚠️ Plugin | ⚠️ Manual |
34
- | **Images (JPEG/PNG)** | ✅ | ✅ | ✅ |
35
- | **Links/URLs** | ✅ | ✅ | ✅ |
36
- | **Multi-page** | | ✅ | |
37
- | **Custom Fonts** | | ✅ | ✅ |
38
- | **Vector Graphics** | ⚠️ Basic | ✅ | ✅ Full |
39
- | **Forms/Fields** | ❌ | ✅ | ✅ |
40
- | **Encryption** | ❌ | ✅ | ✅ |
41
- | **TypeScript Native** | | | |
42
- | **Fluent API** | ✅ | ⚠️ Partial | ✅ |
43
- | **Browser Support** | ✅ | ✅ | ❌ |
44
- | **Node.js/Bun** | | | ✅ |
45
-
46
- > **podpdf** - Best balance of size, speed, and features for common use-cases (invoices, reports, tables)
26
+ ### Core Features
27
+
28
+ | Feature | podpdf | podpdf/plus | podpdf/browser |
29
+ |---------|:------:|:-----------:|:--------------:|
30
+ | Text & Styling | ✅ | ✅ | ✅ |
31
+ | Text Wrap & Alignment | ✅ | ✅ | ✅ |
32
+ | Shapes (rect, circle, line) | ✅ | ✅ | ✅ |
33
+ | Tables | ✅ | ✅ | ✅ |
34
+ | Images (JPEG) | ✅ | ✅ | ✅ |
35
+ | Images (PNG) | | ✅ | |
36
+ | Links/URLs | ✅ | | |
37
+ | Multi-page | ✅ | ✅ | ✅ |
38
+ | Document Metadata | ✅ | ✅ | ✅ |
39
+ | Custom Fonts (TTF) | | ✅ | |
40
+ | TypeScript Native | | ✅ | ✅ |
41
+
42
+ ### Environment Support
43
+
44
+ | Platform | podpdf | podpdf/plus | podpdf/browser |
45
+ |----------|:------:|:-----------:|:--------------:|
46
+ | Node.js / Bun | ✅ | ✅ | ❌ |
47
+ | Browser | Manual | Manual | ✅ Native |
48
+ | File System (.save) | ✅ | ✅ | ❌ |
49
+ | Browser Download (.download) | | | |
50
+
51
+ **Choose the right variant:**
52
+ - `podpdf` - Node.js/Bun for invoices, reports, tables
53
+ - `podpdf/plus` - Need PNG images or custom fonts
54
+ - `podpdf/browser` - Browser-native PDF generation
47
55
 
48
56
  ## Installation
49
57
 
@@ -57,8 +65,20 @@ pnpm add podpdf
57
65
  bun add podpdf
58
66
  ```
59
67
 
68
+ ## Package Variants
69
+
70
+ podpdf provides **3 specialized exports** for different use cases:
71
+
72
+ | Import | Use Case | Key Features |
73
+ |--------|----------|--------------|
74
+ | `podpdf` | Node.js/Bun | Core features, `.save()` to file |
75
+ | `podpdf/plus` | Node.js/Bun | PNG images + custom TTF fonts |
76
+ | `podpdf/browser` | Browser | Browser-native, `.download()` method |
77
+
60
78
  ## Quick Start
61
79
 
80
+ ### Node.js / Bun
81
+
62
82
  ```typescript
63
83
  import { pdf } from 'podpdf'
64
84
 
@@ -68,16 +88,48 @@ await pdf('A4')
68
88
  .save('hello.pdf')
69
89
  ```
70
90
 
91
+ ### Browser
92
+
93
+ ```typescript
94
+ import { pdf } from 'podpdf/browser'
95
+
96
+ pdf('A4')
97
+ .text('Hello Browser!', 50, 50, { size: 24, weight: 'bold' })
98
+ .rect(50, 80, 200, 100, { fill: '#3498db', radius: 10 })
99
+ .download('hello.pdf') // Triggers browser download
100
+ ```
101
+
71
102
  ## Features
72
103
 
73
104
  - **Text** - Multiple fonts, sizes, colors, alignment, text wrapping
74
105
  - **Shapes** - Rectangle, rounded rectangle, circle, line (solid & dashed)
75
106
  - **Tables** - Easy table creation with headers, styling, alignment
76
- - **Images** - JPEG and PNG support
107
+ - **Images** - JPEG support (PNG via podpdf/plus)
77
108
  - **Links** - Clickable URLs with optional underline
78
109
  - **Multi-page** - Multiple pages with different sizes
110
+ - **Metadata** - Document title, author, subject, keywords
79
111
  - **Fluent API** - Chainable methods for clean code
80
112
 
113
+ ### podpdf/plus (Extended)
114
+
115
+ For PNG images and custom fonts, use `podpdf/plus`:
116
+
117
+ ```typescript
118
+ import { pdfPlus } from 'podpdf/plus'
119
+
120
+ // Load custom font
121
+ const fontData = await Bun.file('custom-font.ttf').bytes()
122
+
123
+ // Load PNG image
124
+ const pngData = await Bun.file('logo.png').bytes()
125
+
126
+ await pdfPlus('A4')
127
+ .registerFont('custom', fontData)
128
+ .text('Custom Font Text', 50, 50, { font: 'custom' })
129
+ .imagePng(pngData, 50, 100, { width: 200 }) // async method
130
+ .save('output.pdf')
131
+ ```
132
+
81
133
  ## API Reference
82
134
 
83
135
  ### Create Document
@@ -190,6 +242,24 @@ const imageData = await Bun.file('photo.jpg').bytes()
190
242
  .page({ width: 500, height: 700 }) // Custom
191
243
  ```
192
244
 
245
+ ### Metadata
246
+
247
+ ```typescript
248
+ .metadata({ title?, author?, subject?, keywords?, creator? })
249
+ ```
250
+
251
+ ```typescript
252
+ pdf('A4')
253
+ .metadata({
254
+ title: 'Invoice #123',
255
+ author: 'Company Name',
256
+ subject: 'Monthly Invoice',
257
+ keywords: 'invoice, billing'
258
+ })
259
+ .text('...', 50, 50)
260
+ .save('invoice.pdf')
261
+ ```
262
+
193
263
  ### Output
194
264
 
195
265
  ```typescript
@@ -362,6 +432,7 @@ import type {
362
432
  Align, // 'left' | 'center' | 'right'
363
433
  Weight, // 'normal' | 'bold' | 'italic' | 'bolditalic'
364
434
  Size, // { width, height }
435
+ PDFMetadata, // { title?, author?, subject?, keywords?, creator? }
365
436
  TextOpts,
366
437
  RectOpts,
367
438
  LineOpts,
@@ -389,12 +460,52 @@ Tested with 1000 document generations:
389
460
 
390
461
  ## Browser Support
391
462
 
392
- podpdf is designed for Node.js and Bun. For browser usage, the `build()` method returns a `Uint8Array` that can be converted to a Blob:
463
+ ### podpdf/browser (Recommended for Browser)
464
+
465
+ For browser environments, use the dedicated `podpdf/browser` module with built-in download support:
466
+
467
+ ```typescript
468
+ import { pdf } from 'podpdf/browser'
469
+
470
+ // Create and download PDF directly in browser
471
+ pdf('A4')
472
+ .text('Hello from Browser!', 50, 50, { size: 24, weight: 'bold' })
473
+ .rect(50, 80, 200, 100, { fill: '#3498db', radius: 10 })
474
+ .download('document.pdf') // Triggers browser download
475
+
476
+ // Or get as Blob for custom handling
477
+ const blob = doc.toBlob()
478
+
479
+ // Or get data URL for iframe preview
480
+ const dataURL = doc.toDataURL()
481
+ const iframe = document.createElement('iframe')
482
+ iframe.src = dataURL
483
+ ```
484
+
485
+ **Key differences in `podpdf/browser`:**
486
+ - ✅ No Node.js dependencies (fully browser-compatible)
487
+ - ✅ `download(filename)` - Directly triggers browser download
488
+ - ✅ `toBlob()` - Returns Blob object
489
+ - ✅ `toDataURL()` - Returns object URL for preview
490
+ - ❌ No `save()` method (use `download()` instead)
491
+ - ✅ Same API for text, shapes, tables, images, etc.
492
+
493
+ ### Using Core podpdf in Browser
494
+
495
+ The main `podpdf` module can also work in browsers using the `build()` method:
393
496
 
394
497
  ```typescript
498
+ import { pdf } from 'podpdf'
499
+
395
500
  const bytes = doc.build()
396
501
  const blob = new Blob([bytes], { type: 'application/pdf' })
397
502
  const url = URL.createObjectURL(blob)
503
+
504
+ // Trigger download
505
+ const a = document.createElement('a')
506
+ a.href = url
507
+ a.download = 'document.pdf'
508
+ a.click()
398
509
  ```
399
510
 
400
511
  ## License
@@ -0,0 +1,93 @@
1
+ export type Color = string | [number, number, number];
2
+ export type Align = 'left' | 'center' | 'right';
3
+ export type Weight = 'normal' | 'bold' | 'italic' | 'bolditalic';
4
+ export interface Size {
5
+ width: number;
6
+ height: number;
7
+ }
8
+ export interface TextOpts {
9
+ size?: number;
10
+ color?: Color;
11
+ align?: Align;
12
+ weight?: Weight;
13
+ maxWidth?: number;
14
+ font?: string;
15
+ }
16
+ export interface RectOpts {
17
+ fill?: Color;
18
+ stroke?: Color;
19
+ lineWidth?: number;
20
+ radius?: number;
21
+ }
22
+ export interface LineOpts {
23
+ color?: Color;
24
+ width?: number;
25
+ dash?: number[];
26
+ }
27
+ export interface CircleOpts {
28
+ fill?: Color;
29
+ stroke?: Color;
30
+ lineWidth?: number;
31
+ }
32
+ export interface ImageOpts {
33
+ width?: number;
34
+ height?: number;
35
+ }
36
+ export interface LinkOpts {
37
+ underline?: boolean;
38
+ color?: Color;
39
+ }
40
+ export interface TableCol {
41
+ header: string;
42
+ width?: number;
43
+ align?: Align;
44
+ }
45
+ export interface TableOpts {
46
+ columns: TableCol[];
47
+ headerBg?: Color;
48
+ headerColor?: Color;
49
+ borderColor?: Color;
50
+ fontSize?: number;
51
+ padding?: number;
52
+ }
53
+ export interface PDFMetadata {
54
+ title?: string;
55
+ author?: string;
56
+ subject?: string;
57
+ keywords?: string;
58
+ creator?: string;
59
+ }
60
+ export declare const SIZES: Record<string, Size>;
61
+ export declare class PDF {
62
+ private pages;
63
+ private cur;
64
+ private sz;
65
+ private meta?;
66
+ constructor(s?: Size | keyof typeof SIZES);
67
+ metadata(m: PDFMetadata): this;
68
+ page(s?: Size | keyof typeof SIZES): this;
69
+ text(t: string, x: number, y: number, o?: TextOpts): this;
70
+ rect(x: number, y: number, w: number, h: number, o?: RectOpts): this;
71
+ line(x1: number, y1: number, x2: number, y2: number, o?: LineOpts): this;
72
+ circle(cx: number, cy: number, r: number, o?: CircleOpts): this;
73
+ image(d: Uint8Array, x: number, y: number, o?: ImageOpts): this;
74
+ link(t: string, url: string, x: number, y: number, o?: LinkOpts): this;
75
+ table(data: string[][], x: number, y: number, o: TableOpts): this;
76
+ private ensure;
77
+ build(): Uint8Array;
78
+ /**
79
+ * Download PDF in browser using Blob and URL APIs
80
+ * @param filename - The filename for the downloaded PDF (default: 'document.pdf')
81
+ */
82
+ download(filename?: string): void;
83
+ /**
84
+ * Get PDF as Blob object (useful for preview or custom handling)
85
+ */
86
+ toBlob(): Blob;
87
+ /**
88
+ * Get PDF as data URL (useful for iframe preview)
89
+ */
90
+ toDataURL(): string;
91
+ }
92
+ export declare const pdf: (s?: Size | keyof typeof SIZES) => PDF;
93
+ //# sourceMappingURL=browser.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"browser.d.ts","sourceRoot":"","sources":["../src/browser.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ var P={A4:{width:595,height:842},A3:{width:842,height:1191},A5:{width:420,height:595},LETTER:{width:612,height:792}},g={normal:"Helvetica",bold:"Helvetica-Bold",italic:"Helvetica-Oblique",bolditalic:"Helvetica-BoldOblique"},F=(q)=>{if(Array.isArray(q))return q;let B=q.replace("#","");if(B.length===3)return[parseInt(B[0]+B[0],16)/255,parseInt(B[1]+B[1],16)/255,parseInt(B[2]+B[2],16)/255];return[parseInt(B.slice(0,2),16)/255,parseInt(B.slice(2,4),16)/255,parseInt(B.slice(4,6),16)/255]},A=(q)=>{let[B,z,H]=F(q);return`${B.toFixed(3)} ${z.toFixed(3)} ${H.toFixed(3)} rg`},D=(q)=>{let[B,z,H]=F(q);return`${B.toFixed(3)} ${z.toFixed(3)} ${H.toFixed(3)} RG`},E=(q)=>q.replace(/\\/g,"\\\\").replace(/\(/g,"\\(").replace(/\)/g,"\\)"),J=(q)=>Number.isInteger(q)?q.toString():q.toFixed(2),j=(q,B)=>q.length*B*0.52;class R{c=[];s=0;e=new TextEncoder;w(q){let B=typeof q==="string"?this.e.encode(q):q;return this.c.push(B),this.s+=B.length,this}l(q){return this.w(q+`
2
+ `)}size(){return this.s}out(){let q=new Uint8Array(this.s),B=0;for(let z of this.c)q.set(z,B),B+=z.length;return q}}class v{w;h;c=[];f=new Set;imgs=[];links=[];ic=0;constructor(q){this.w=q.width,this.h=q.height}text(q,B,z,H={}){let C=H.size??12,K=H.weight??"normal",Q=H.color??"#000",W=H.align??"left",N=g[K];this.f.add(N);let G=this.h-z,L=B,X=H.maxWidth?this.wrap(q,H.maxWidth,C):[q];for(let V of X)L=W==="center"?B-j(V,C)/2:W==="right"?B-j(V,C):B,this.c.push("q","BT",A(Q),`/${N.replace("-","")} ${C} Tf`,`${J(L)} ${J(G)} Td`,`(${E(V)}) Tj`,"ET","Q"),G-=C*1.2;return this}rect(q,B,z,H,C={}){let K=this.h-B-H;if(this.c.push("q"),C.radius&&C.radius>0){let Q=Math.min(C.radius,z/2,H/2);this.c.push(`${J(q+Q)} ${J(K)} m`,`${J(q+z-Q)} ${J(K)} l`,`${J(q+z)} ${J(K)} ${J(q+z)} ${J(K+Q)} y`,`${J(q+z)} ${J(K+H-Q)} l`,`${J(q+z)} ${J(K+H)} ${J(q+z-Q)} ${J(K+H)} y`,`${J(q+Q)} ${J(K+H)} l`,`${J(q)} ${J(K+H)} ${J(q)} ${J(K+H-Q)} y`,`${J(q)} ${J(K+Q)} l`,`${J(q)} ${J(K)} ${J(q+Q)} ${J(K)} y`,"h")}else this.c.push(`${J(q)} ${J(K)} ${J(z)} ${J(H)} re`);if(C.fill)this.c.push(A(C.fill)),this.c.push(C.stroke?"B":"f");if(C.stroke){if(this.c.push(D(C.stroke)),C.lineWidth)this.c.push(`${C.lineWidth} w`);if(!C.fill)this.c.push("S")}return this.c.push("Q"),this}line(q,B,z,H,C={}){if(this.c.push("q"),C.color)this.c.push(D(C.color));if(C.width)this.c.push(`${C.width} w`);if(C.dash)this.c.push(`[${C.dash.join(" ")}] 0 d`);return this.c.push(`${J(q)} ${J(this.h-B)} m`,`${J(z)} ${J(this.h-H)} l`,"S","Q"),this}circle(q,B,z,H={}){let C=this.h-B;if(this.c.push("q"),this.c.push(`${J(q+z)} ${J(C)} m`,`${J(q+z)} ${J(C+z*0.5523)} ${J(q+z*0.5523)} ${J(C+z)} ${J(q)} ${J(C+z)} c`,`${J(q-z*0.5523)} ${J(C+z)} ${J(q-z)} ${J(C+z*0.5523)} ${J(q-z)} ${J(C)} c`,`${J(q-z*0.5523)} ${J(C-z)} ${J(q-z)} ${J(C-z*0.5523)} ${J(q)} ${J(C-z)} c`,`${J(q+z*0.5523)} ${J(C-z)} ${J(q+z)} ${J(C-z*0.5523)} ${J(q+z)} ${J(C)} c`),H.fill)this.c.push(A(H.fill)),this.c.push(H.stroke?"B":"f");if(H.stroke){if(this.c.push(D(H.stroke)),H.lineWidth)this.c.push(`${H.lineWidth} w`);if(!H.fill)this.c.push("S")}return this.c.push("Q"),this}image(q,B,z,H={}){let C=this.imgInfo(q);if(!C)return this;let K=H.width??C.w,Q=H.height??C.h,W=`I${++this.ic}`;return this.imgs.push({d:q,w:C.w,h:C.h,x:B,y:this.h-z-Q,id:W}),this.c.push("q",`${J(K)} 0 0 ${J(Q)} ${J(B)} ${J(this.h-z-Q)} cm`,`/${W} Do`,"Q"),this}link(q,B,z,H,C={}){let K=C.color??"#00E";this.text(q,z,H,{color:K,size:12});let W=j(q,12);if(C.underline!==!1)this.line(z,H+2,z+W,H+2,{color:K,width:0.5});return this.links.push({x:z,y:this.h-H-12,w:W,h:12,url:B}),this}table(q,B,z,H){let C=H.padding??8,K=H.fontSize??10,Q=K+C*2,W=H.columns.map((X,V)=>X.width??Math.max(j(X.header,K),...q.map((O)=>j(O[V]??"",K)))+C*2),N=W.reduce((X,V)=>X+V,0),G=z;this.rect(B,G,N,Q,{fill:H.headerBg??"#F0F0F0"});let L=B;for(let X=0;X<H.columns.length;X++){let V=H.columns[X];this.text(V.header,L+(V.align==="center"?W[X]/2:V.align==="right"?W[X]-C:C),G+C+K*0.8,{size:K,weight:"bold",color:H.headerColor??"#000",align:V.align}),L+=W[X]}G+=Q;for(let X=0;X<q.length;X++){this.rect(B,G,N,Q,{fill:X%2?"#F9F9F9":"#FFF"}),L=B;for(let V=0;V<H.columns.length;V++){let O=H.columns[V];this.text(q[X][V]??"",L+(O.align==="center"?W[V]/2:O.align==="right"?W[V]-C:C),G+C+K*0.8,{size:K,align:O.align}),L+=W[V]}G+=Q}return this.rect(B,z,N,Q*(q.length+1),{stroke:H.borderColor??"#CCC"}),this}wrap(q,B,z){let H=q.split(" "),C=[],K="";for(let Q of H){let W=K?`${K} ${Q}`:Q;if(j(W,z)<=B)K=W;else{if(K)C.push(K);K=Q}}if(K)C.push(K);return C}imgInfo(q){if(q[0]===255&&q[1]===216){let B=2;while(B<q.length){if(q[B]!==255)break;let z=q[B+1];if(z>=192&&z<=207&&z!==196&&z!==200&&z!==204)return{h:q[B+5]<<8|q[B+6],w:q[B+7]<<8|q[B+8]};B+=2+(q[B+2]<<8|q[B+3])}}if(q[0]===137&&q[1]===80)return{w:q[16]<<24|q[17]<<16|q[18]<<8|q[19],h:q[20]<<24|q[21]<<16|q[22]<<8|q[23]};return null}}class S{pages=[];cur=null;sz;meta;constructor(q="A4"){this.sz=typeof q==="string"?P[q]:q}metadata(q){return this.meta=q,this}page(q){return this.cur=new v(q?typeof q==="string"?P[q]:q:this.sz),this.pages.push(this.cur),this}text(q,B,z,H){return this.ensure().text(q,B,z,H),this}rect(q,B,z,H,C){return this.ensure().rect(q,B,z,H,C),this}line(q,B,z,H,C){return this.ensure().line(q,B,z,H,C),this}circle(q,B,z,H){return this.ensure().circle(q,B,z,H),this}image(q,B,z,H){return this.ensure().image(q,B,z,H),this}link(q,B,z,H,C){return this.ensure().link(q,B,z,H,C),this}table(q,B,z,H){return this.ensure().table(q,B,z,H),this}ensure(){if(!this.cur)this.page();return this.cur}build(){let q=new R,B=[0],z=0;q.l("%PDF-1.4").l("%µµµµ");let H=new Set;this.pages.forEach((M)=>M.f.forEach((_)=>H.add(_)));let C=Array.from(H),K={};for(let M of C){let _=++z;K[M]=_,B[_]=q.size(),q.l(`${_} 0 obj`).l(`<</Type/Font/Subtype/Type1/BaseFont/${M}>>`).l("endobj")}let Q=[],W=[],N=[];for(let M of this.pages){let _=[];for(let Y of M.imgs){let T=++z;_.push(T),B[T]=q.size();let u=String.fromCharCode(...Y.d);q.l(`${T} 0 obj`).l(`<</Type/XObject/Subtype/Image/Width ${Y.w}/Height ${Y.h}/ColorSpace/DeviceRGB/BitsPerComponent 8/Filter/DCTDecode/Length ${Y.d.length}>>`).l("stream").w(u).l("").l("endstream").l("endobj")}N.push(_);let $=M.c.join(`
3
+ `),Z=new TextEncoder().encode($).length,U=++z;Q.push(U),B[U]=q.size(),q.l(`${U} 0 obj`).l(`<</Length ${Z}>>`).l("stream").w($).l("").l("endstream").l("endobj");let k=[];for(let Y of M.links){let T=++z;k.push(T),B[T]=q.size(),q.l(`${T} 0 obj`).l(`<</Type/Annot/Subtype/Link/Rect[${Y.x} ${Y.y} ${Y.x+Y.w} ${Y.y+Y.h}]/Border[0 0 0]/A<</Type/Action/S/URI/URI(${Y.url})>>>>`).l("endobj")}W.push(k)}let G=++z,L=z+1,X=this.pages.map((M,_)=>L+_);B[G]=q.size(),q.l(`${G} 0 obj`).l(`<</Type/Pages/Kids[${X.map((M)=>`${M} 0 R`).join(" ")}]/Count ${X.length}>>`).l("endobj");for(let M=0;M<this.pages.length;M++){let _=this.pages[M],$=++z,Z=Array.from(_.f).map((Y)=>`/${Y.replace("-","")} ${K[Y]} 0 R`).join(""),U=_.imgs.map((Y,T)=>`/${Y.id} ${N[M][T]} 0 R`).join(""),k=W[M].length?`/Annots[${W[M].map((Y)=>`${Y} 0 R`).join(" ")}]`:"";B[$]=q.size(),q.l(`${$} 0 obj`).l(`<</Type/Page/Parent ${G} 0 R/MediaBox[0 0 ${_.w} ${_.h}]/Contents ${Q[M]} 0 R/Resources<<${Z?`/Font<<${Z}>>`:""}${U?`/XObject<<${U}>>`:""}>>${k}>>`).l("endobj")}let V=0;if(this.meta){V=++z,B[V]=q.size();let M=new Date,_=`D:${M.getFullYear()}${String(M.getMonth()+1).padStart(2,"0")}${String(M.getDate()).padStart(2,"0")}${String(M.getHours()).padStart(2,"0")}${String(M.getMinutes()).padStart(2,"0")}${String(M.getSeconds()).padStart(2,"0")}`,$=this.meta;q.l(`${V} 0 obj`).l(`<<${$.title?`/Title(${E($.title)})`:""}${$.author?`/Author(${E($.author)})`:""}${$.subject?`/Subject(${E($.subject)})`:""}${$.keywords?`/Keywords(${E($.keywords)})`:""}${$.creator?`/Creator(${E($.creator)})`:""}/Producer(podpdf-browser)/CreationDate(${_})>>`).l("endobj")}let O=++z;B[O]=q.size(),q.l(`${O} 0 obj`).l(`<</Type/Catalog/Pages ${G} 0 R>>`).l("endobj");let b=q.size();q.l("xref").l(`0 ${z+1}`).l("0000000000 65535 f ");for(let M=1;M<=z;M++)q.l(`${B[M].toString().padStart(10,"0")} 00000 n `);return q.l("trailer").l(`<</Size ${z+1}/Root ${O} 0 R${V?`/Info ${V} 0 R`:""}>>`).l("startxref").l(b.toString()).l("%%EOF"),q.out()}download(q="document.pdf"){if(typeof window>"u")throw Error("download() method is only available in browser environment. Use build() to get Uint8Array instead.");let B=this.build(),z=new Blob([B],{type:"application/pdf"}),H=URL.createObjectURL(z),C=document.createElement("a");C.href=H,C.download=q,C.style.display="none",document.body.appendChild(C),C.click(),document.body.removeChild(C),URL.revokeObjectURL(H)}toBlob(){let q=this.build();return new Blob([q],{type:"application/pdf"})}toDataURL(){let q=this.build(),B=new Blob([q],{type:"application/pdf"});return URL.createObjectURL(B)}}var I=(q)=>new S(q);export{I as pdf,P as SIZES,S as PDF};
package/dist/index.d.ts CHANGED
@@ -11,6 +11,7 @@ export interface TextOpts {
11
11
  align?: Align;
12
12
  weight?: Weight;
13
13
  maxWidth?: number;
14
+ font?: string;
14
15
  }
15
16
  export interface RectOpts {
16
17
  fill?: Color;
@@ -49,12 +50,21 @@ export interface TableOpts {
49
50
  fontSize?: number;
50
51
  padding?: number;
51
52
  }
53
+ export interface PDFMetadata {
54
+ title?: string;
55
+ author?: string;
56
+ subject?: string;
57
+ keywords?: string;
58
+ creator?: string;
59
+ }
52
60
  export declare const SIZES: Record<string, Size>;
53
61
  export declare class PDF {
54
62
  private pages;
55
63
  private cur;
56
64
  private sz;
65
+ private meta?;
57
66
  constructor(s?: Size | keyof typeof SIZES);
67
+ metadata(m: PDFMetadata): this;
58
68
  page(s?: Size | keyof typeof SIZES): this;
59
69
  text(t: string, x: number, y: number, o?: TextOpts): this;
60
70
  rect(x: number, y: number, w: number, h: number, o?: RectOpts): this;
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/dist/index.js CHANGED
@@ -1,3 +1,3 @@
1
- import{createRequire as U}from"node:module";var B=Object.create;var{getPrototypeOf:v,defineProperty:z,getOwnPropertyNames:E}=Object;var W=Object.prototype.hasOwnProperty;var L=(e,n,t)=>{t=e!=null?B(v(e)):{};let i=n||!e||!e.__esModule?z(t,"default",{value:e,enumerable:!0}):t;for(let r of E(e))if(!W.call(i,r))z(i,r,{get:()=>e[r],enumerable:!0});return i};var P=U(import.meta.url);var O={A4:{width:595,height:842},A3:{width:842,height:1191},A5:{width:420,height:595},LETTER:{width:612,height:792}},q={normal:"Helvetica",bold:"Helvetica-Bold",italic:"Helvetica-Oblique",bolditalic:"Helvetica-BoldOblique"},T=(e)=>{if(Array.isArray(e))return e;let n=e.replace("#","");if(n.length===3)return[parseInt(n[0]+n[0],16)/255,parseInt(n[1]+n[1],16)/255,parseInt(n[2]+n[2],16)/255];return[parseInt(n.slice(0,2),16)/255,parseInt(n.slice(2,4),16)/255,parseInt(n.slice(4,6),16)/255]},I=(e)=>{let[n,t,i]=T(e);return`${n.toFixed(3)} ${t.toFixed(3)} ${i.toFixed(3)} rg`},F=(e)=>{let[n,t,i]=T(e);return`${n.toFixed(3)} ${t.toFixed(3)} ${i.toFixed(3)} RG`},D=(e)=>e.replace(/\\/g,"\\\\").replace(/\(/g,"\\(").replace(/\)/g,"\\)"),s=(e)=>Number.isInteger(e)?e.toString():e.toFixed(2),y=(e,n)=>e.length*n*0.5;class x{c=[];s=0;e=new TextEncoder;w(e){let n=typeof e==="string"?this.e.encode(e):e;return this.c.push(n),this.s+=n.length,this}l(e){return this.w(e+`
2
- `)}size(){return this.s}out(){let e=new Uint8Array(this.s),n=0;for(let t of this.c)e.set(t,n),n+=t.length;return e}}class A{w;h;c=[];f=new Set;imgs=[];links=[];ic=0;constructor(e){this.w=e.width,this.h=e.height}text(e,n,t,i={}){let r=i.size??12,o=i.weight??"normal",l=i.color??"#000",u=i.align??"left",$=q[o];this.f.add($);let g=this.h-t,b=n,a=i.maxWidth?this.wrap(e,i.maxWidth,r):[e];for(let h of a)b=u==="center"?n-y(h,r)/2:u==="right"?n-y(h,r):n,this.c.push("q","BT",I(l),`/${$.replace("-","")} ${r} Tf`,`${s(b)} ${s(g)} Td`,`(${D(h)}) Tj`,"ET","Q"),g-=r*1.2;return this}rect(e,n,t,i,r={}){let o=this.h-n-i;if(this.c.push("q"),r.radius&&r.radius>0){let l=Math.min(r.radius,t/2,i/2);this.c.push(`${s(e+l)} ${s(o)} m`,`${s(e+t-l)} ${s(o)} l`,`${s(e+t)} ${s(o)} ${s(e+t)} ${s(o+l)} y`,`${s(e+t)} ${s(o+i-l)} l`,`${s(e+t)} ${s(o+i)} ${s(e+t-l)} ${s(o+i)} y`,`${s(e+l)} ${s(o+i)} l`,`${s(e)} ${s(o+i)} ${s(e)} ${s(o+i-l)} y`,`${s(e)} ${s(o+l)} l`,`${s(e)} ${s(o)} ${s(e+l)} ${s(o)} y`,"h")}else this.c.push(`${s(e)} ${s(o)} ${s(t)} ${s(i)} re`);if(r.fill)this.c.push(I(r.fill)),this.c.push(r.stroke?"B":"f");if(r.stroke){if(this.c.push(F(r.stroke)),r.lineWidth)this.c.push(`${r.lineWidth} w`);if(!r.fill)this.c.push("S")}return this.c.push("Q"),this}line(e,n,t,i,r={}){if(this.c.push("q"),r.color)this.c.push(F(r.color));if(r.width)this.c.push(`${r.width} w`);if(r.dash)this.c.push(`[${r.dash.join(" ")}] 0 d`);return this.c.push(`${s(e)} ${s(this.h-n)} m`,`${s(t)} ${s(this.h-i)} l`,"S","Q"),this}circle(e,n,t,i={}){let r=this.h-n;if(this.c.push("q"),this.c.push(`${s(e+t)} ${s(r)} m`,`${s(e+t)} ${s(r+t*0.5523)} ${s(e+t*0.5523)} ${s(r+t)} ${s(e)} ${s(r+t)} c`,`${s(e-t*0.5523)} ${s(r+t)} ${s(e-t)} ${s(r+t*0.5523)} ${s(e-t)} ${s(r)} c`,`${s(e-t*0.5523)} ${s(r-t)} ${s(e-t)} ${s(r-t*0.5523)} ${s(e)} ${s(r-t)} c`,`${s(e+t*0.5523)} ${s(r-t)} ${s(e+t)} ${s(r-t*0.5523)} ${s(e+t)} ${s(r)} c`),i.fill)this.c.push(I(i.fill)),this.c.push(i.stroke?"B":"f");if(i.stroke){if(this.c.push(F(i.stroke)),i.lineWidth)this.c.push(`${i.lineWidth} w`);if(!i.fill)this.c.push("S")}return this.c.push("Q"),this}image(e,n,t,i={}){let r=this.imgInfo(e);if(!r)return this;let o=i.width??r.w,l=i.height??r.h,u=`I${++this.ic}`;return this.imgs.push({d:e,w:r.w,h:r.h,x:n,y:this.h-t-l,id:u}),this.c.push("q",`${s(o)} 0 0 ${s(l)} ${s(n)} ${s(this.h-t-l)} cm`,`/${u} Do`,"Q"),this}link(e,n,t,i,r={}){let o=r.color??"#00E";this.text(e,t,i,{color:o,size:12});let u=y(e,12);if(r.underline!==!1)this.line(t,i+2,t+u,i+2,{color:o,width:0.5});return this.links.push({x:t,y:this.h-i-12,w:u,h:12,url:n}),this}table(e,n,t,i){let r=i.padding??8,o=i.fontSize??10,l=o+r*2,u=i.columns.map((a,h)=>a.width??Math.max(y(a.header,o),...e.map((d)=>y(d[h]??"",o)))+r*2),$=u.reduce((a,h)=>a+h,0),g=t;this.rect(n,g,$,l,{fill:i.headerBg??"#F0F0F0"});let b=n;for(let a=0;a<i.columns.length;a++){let h=i.columns[a];this.text(h.header,b+(h.align==="center"?u[a]/2:h.align==="right"?u[a]-r:r),g+r+o*0.8,{size:o,weight:"bold",color:i.headerColor??"#000",align:h.align}),b+=u[a]}g+=l;for(let a=0;a<e.length;a++){this.rect(n,g,$,l,{fill:a%2?"#F9F9F9":"#FFF"}),b=n;for(let h=0;h<i.columns.length;h++){let d=i.columns[h];this.text(e[a][h]??"",b+(d.align==="center"?u[h]/2:d.align==="right"?u[h]-r:r),g+r+o*0.8,{size:o,align:d.align}),b+=u[h]}g+=l}return this.rect(n,t,$,l*(e.length+1),{stroke:i.borderColor??"#CCC"}),this}wrap(e,n,t){let i=e.split(" "),r=[],o="";for(let l of i){let u=o?`${o} ${l}`:l;if(y(u,t)<=n)o=u;else{if(o)r.push(o);o=l}}if(o)r.push(o);return r}imgInfo(e){if(e[0]===255&&e[1]===216){let n=2;while(n<e.length){if(e[n]!==255)break;let t=e[n+1];if(t>=192&&t<=207&&t!==196&&t!==200&&t!==204)return{h:e[n+5]<<8|e[n+6],w:e[n+7]<<8|e[n+8]};n+=2+(e[n+2]<<8|e[n+3])}}if(e[0]===137&&e[1]===80)return{w:e[16]<<24|e[17]<<16|e[18]<<8|e[19],h:e[20]<<24|e[21]<<16|e[22]<<8|e[23]};return null}}class R{pages=[];cur=null;sz;constructor(e="A4"){this.sz=typeof e==="string"?O[e]:e}page(e){return this.cur=new A(e?typeof e==="string"?O[e]:e:this.sz),this.pages.push(this.cur),this}text(e,n,t,i){return this.ensure().text(e,n,t,i),this}rect(e,n,t,i,r){return this.ensure().rect(e,n,t,i,r),this}line(e,n,t,i,r){return this.ensure().line(e,n,t,i,r),this}circle(e,n,t,i){return this.ensure().circle(e,n,t,i),this}image(e,n,t,i){return this.ensure().image(e,n,t,i),this}link(e,n,t,i,r){return this.ensure().link(e,n,t,i,r),this}table(e,n,t,i){return this.ensure().table(e,n,t,i),this}ensure(){if(!this.cur)this.page();return this.cur}build(){let e=new x,n=[0],t=0;e.l("%PDF-1.4").l("%µµµµ");let i=new Set;this.pages.forEach((c)=>c.f.forEach((m)=>i.add(m)));let r=Array.from(i),o={};for(let c of r){let m=++t;o[c]=m,n[m]=e.size(),e.l(`${m} 0 obj`).l(`<</Type/Font/Subtype/Type1/BaseFont/${c}>>`).l("endobj")}let l=[],u=[],$=[];for(let c of this.pages){let m=[];for(let p of c.imgs){let f=++t;m.push(f),n[f]=e.size();let j=String.fromCharCode(...p.d);e.l(`${f} 0 obj`).l(`<</Type/XObject/Subtype/Image/Width ${p.w}/Height ${p.h}/ColorSpace/DeviceRGB/BitsPerComponent 8/Filter/DCTDecode/Length ${p.d.length}>>`).l("stream").w(j).l("").l("endstream").l("endobj")}$.push(m);let C=c.c.join(`
3
- `),S=new TextEncoder().encode(C).length,w=++t;l.push(w),n[w]=e.size(),e.l(`${w} 0 obj`).l(`<</Length ${S}>>`).l("stream").w(C).l("").l("endstream").l("endobj");let k=[];for(let p of c.links){let f=++t;k.push(f),n[f]=e.size(),e.l(`${f} 0 obj`).l(`<</Type/Annot/Subtype/Link/Rect[${p.x} ${p.y} ${p.x+p.w} ${p.y+p.h}]/Border[0 0 0]/A<</Type/Action/S/URI/URI(${p.url})>>>>`).l("endobj")}u.push(k)}let g=++t,b=t+1,a=this.pages.map((c,m)=>b+m);n[g]=e.size(),e.l(`${g} 0 obj`).l(`<</Type/Pages/Kids[${a.map((c)=>`${c} 0 R`).join(" ")}]/Count ${a.length}>>`).l("endobj");for(let c=0;c<this.pages.length;c++){let m=this.pages[c],C=++t,S=Array.from(m.f).map((p)=>`/${p.replace("-","")} ${o[p]} 0 R`).join(""),w=m.imgs.map((p,f)=>`/${p.id} ${$[c][f]} 0 R`).join(""),k=u[c].length?`/Annots[${u[c].map((p)=>`${p} 0 R`).join(" ")}]`:"";n[C]=e.size(),e.l(`${C} 0 obj`).l(`<</Type/Page/Parent ${g} 0 R/MediaBox[0 0 ${m.w} ${m.h}]/Contents ${l[c]} 0 R/Resources<<${S?`/Font<<${S}>>`:""}${w?`/XObject<<${w}>>`:""}>>${k}>>`).l("endobj")}let h=++t;n[h]=e.size(),e.l(`${h} 0 obj`).l(`<</Type/Catalog/Pages ${g} 0 R>>`).l("endobj");let d=e.size();e.l("xref").l(`0 ${t+1}`).l("0000000000 65535 f ");for(let c=1;c<=t;c++)e.l(`${n[c].toString().padStart(10,"0")} 00000 n `);return e.l("trailer").l(`<</Size ${t+1}/Root ${h} 0 R>>`).l("startxref").l(d.toString()).l("%%EOF"),e.out()}async save(e){let n=this.build();if(typeof Bun<"u")await Bun.write(e,n);else{let{writeFile:t}=await import("fs/promises");await t(e,n)}}}var Z=(e)=>new R(e);export{Z as pdf,O as SIZES,R as PDF};
1
+ import{createRequire as U}from"node:module";var D=Object.create;var{getPrototypeOf:E,defineProperty:z,getOwnPropertyNames:W}=Object;var P=Object.prototype.hasOwnProperty;var L=(t,r,e)=>{e=t!=null?D(E(t)):{};let n=r||!t||!t.__esModule?z(e,"default",{value:t,enumerable:!0}):e;for(let i of W(t))if(!P.call(n,i))z(n,i,{get:()=>t[i],enumerable:!0});return n};var M=U(import.meta.url);var T={A4:{width:595,height:842},A3:{width:842,height:1191},A5:{width:420,height:595},LETTER:{width:612,height:792}},q={normal:"Helvetica",bold:"Helvetica-Bold",italic:"Helvetica-Oblique",bolditalic:"Helvetica-BoldOblique"},O=(t)=>{if(Array.isArray(t))return t;let r=t.replace("#","");if(r.length===3)return[parseInt(r[0]+r[0],16)/255,parseInt(r[1]+r[1],16)/255,parseInt(r[2]+r[2],16)/255];return[parseInt(r.slice(0,2),16)/255,parseInt(r.slice(2,4),16)/255,parseInt(r.slice(4,6),16)/255]},I=(t)=>{let[r,e,n]=O(t);return`${r.toFixed(3)} ${e.toFixed(3)} ${n.toFixed(3)} rg`},j=(t)=>{let[r,e,n]=O(t);return`${r.toFixed(3)} ${e.toFixed(3)} ${n.toFixed(3)} RG`},C=(t)=>t.replace(/\\/g,"\\\\").replace(/\(/g,"\\(").replace(/\)/g,"\\)"),s=(t)=>Number.isInteger(t)?t.toString():t.toFixed(2),S=(t,r)=>t.length*r*0.52;class x{c=[];s=0;e=new TextEncoder;w(t){let r=typeof t==="string"?this.e.encode(t):t;return this.c.push(r),this.s+=r.length,this}l(t){return this.w(t+`
2
+ `)}size(){return this.s}out(){let t=new Uint8Array(this.s),r=0;for(let e of this.c)t.set(e,r),r+=e.length;return t}}class A{w;h;c=[];f=new Set;imgs=[];links=[];ic=0;constructor(t){this.w=t.width,this.h=t.height}text(t,r,e,n={}){let i=n.size??12,o=n.weight??"normal",h=n.color??"#000",c=n.align??"left",f=q[o];this.f.add(f);let m=this.h-e,b=r,a=n.maxWidth?this.wrap(t,n.maxWidth,i):[t];for(let u of a)b=c==="center"?r-S(u,i)/2:c==="right"?r-S(u,i):r,this.c.push("q","BT",I(h),`/${f.replace("-","")} ${i} Tf`,`${s(b)} ${s(m)} Td`,`(${C(u)}) Tj`,"ET","Q"),m-=i*1.2;return this}rect(t,r,e,n,i={}){let o=this.h-r-n;if(this.c.push("q"),i.radius&&i.radius>0){let h=Math.min(i.radius,e/2,n/2);this.c.push(`${s(t+h)} ${s(o)} m`,`${s(t+e-h)} ${s(o)} l`,`${s(t+e)} ${s(o)} ${s(t+e)} ${s(o+h)} y`,`${s(t+e)} ${s(o+n-h)} l`,`${s(t+e)} ${s(o+n)} ${s(t+e-h)} ${s(o+n)} y`,`${s(t+h)} ${s(o+n)} l`,`${s(t)} ${s(o+n)} ${s(t)} ${s(o+n-h)} y`,`${s(t)} ${s(o+h)} l`,`${s(t)} ${s(o)} ${s(t+h)} ${s(o)} y`,"h")}else this.c.push(`${s(t)} ${s(o)} ${s(e)} ${s(n)} re`);if(i.fill)this.c.push(I(i.fill)),this.c.push(i.stroke?"B":"f");if(i.stroke){if(this.c.push(j(i.stroke)),i.lineWidth)this.c.push(`${i.lineWidth} w`);if(!i.fill)this.c.push("S")}return this.c.push("Q"),this}line(t,r,e,n,i={}){if(this.c.push("q"),i.color)this.c.push(j(i.color));if(i.width)this.c.push(`${i.width} w`);if(i.dash)this.c.push(`[${i.dash.join(" ")}] 0 d`);return this.c.push(`${s(t)} ${s(this.h-r)} m`,`${s(e)} ${s(this.h-n)} l`,"S","Q"),this}circle(t,r,e,n={}){let i=this.h-r;if(this.c.push("q"),this.c.push(`${s(t+e)} ${s(i)} m`,`${s(t+e)} ${s(i+e*0.5523)} ${s(t+e*0.5523)} ${s(i+e)} ${s(t)} ${s(i+e)} c`,`${s(t-e*0.5523)} ${s(i+e)} ${s(t-e)} ${s(i+e*0.5523)} ${s(t-e)} ${s(i)} c`,`${s(t-e*0.5523)} ${s(i-e)} ${s(t-e)} ${s(i-e*0.5523)} ${s(t)} ${s(i-e)} c`,`${s(t+e*0.5523)} ${s(i-e)} ${s(t+e)} ${s(i-e*0.5523)} ${s(t+e)} ${s(i)} c`),n.fill)this.c.push(I(n.fill)),this.c.push(n.stroke?"B":"f");if(n.stroke){if(this.c.push(j(n.stroke)),n.lineWidth)this.c.push(`${n.lineWidth} w`);if(!n.fill)this.c.push("S")}return this.c.push("Q"),this}image(t,r,e,n={}){let i=this.imgInfo(t);if(!i)return this;let o=n.width??i.w,h=n.height??i.h,c=`I${++this.ic}`;return this.imgs.push({d:t,w:i.w,h:i.h,x:r,y:this.h-e-h,id:c}),this.c.push("q",`${s(o)} 0 0 ${s(h)} ${s(r)} ${s(this.h-e-h)} cm`,`/${c} Do`,"Q"),this}link(t,r,e,n,i={}){let o=i.color??"#00E";this.text(t,e,n,{color:o,size:12});let c=S(t,12);if(i.underline!==!1)this.line(e,n+2,e+c,n+2,{color:o,width:0.5});return this.links.push({x:e,y:this.h-n-12,w:c,h:12,url:r}),this}table(t,r,e,n){let i=n.padding??8,o=n.fontSize??10,h=o+i*2,c=n.columns.map((a,u)=>a.width??Math.max(S(a.header,o),...t.map((d)=>S(d[u]??"",o)))+i*2),f=c.reduce((a,u)=>a+u,0),m=e;this.rect(r,m,f,h,{fill:n.headerBg??"#F0F0F0"});let b=r;for(let a=0;a<n.columns.length;a++){let u=n.columns[a];this.text(u.header,b+(u.align==="center"?c[a]/2:u.align==="right"?c[a]-i:i),m+i+o*0.8,{size:o,weight:"bold",color:n.headerColor??"#000",align:u.align}),b+=c[a]}m+=h;for(let a=0;a<t.length;a++){this.rect(r,m,f,h,{fill:a%2?"#F9F9F9":"#FFF"}),b=r;for(let u=0;u<n.columns.length;u++){let d=n.columns[u];this.text(t[a][u]??"",b+(d.align==="center"?c[u]/2:d.align==="right"?c[u]-i:i),m+i+o*0.8,{size:o,align:d.align}),b+=c[u]}m+=h}return this.rect(r,e,f,h*(t.length+1),{stroke:n.borderColor??"#CCC"}),this}wrap(t,r,e){let n=t.split(" "),i=[],o="";for(let h of n){let c=o?`${o} ${h}`:h;if(S(c,e)<=r)o=c;else{if(o)i.push(o);o=h}}if(o)i.push(o);return i}imgInfo(t){if(t[0]===255&&t[1]===216){let r=2;while(r<t.length){if(t[r]!==255)break;let e=t[r+1];if(e>=192&&e<=207&&e!==196&&e!==200&&e!==204)return{h:t[r+5]<<8|t[r+6],w:t[r+7]<<8|t[r+8]};r+=2+(t[r+2]<<8|t[r+3])}}if(t[0]===137&&t[1]===80)return{w:t[16]<<24|t[17]<<16|t[18]<<8|t[19],h:t[20]<<24|t[21]<<16|t[22]<<8|t[23]};return null}}class R{pages=[];cur=null;sz;meta;constructor(t="A4"){this.sz=typeof t==="string"?T[t]:t}metadata(t){return this.meta=t,this}page(t){return this.cur=new A(t?typeof t==="string"?T[t]:t:this.sz),this.pages.push(this.cur),this}text(t,r,e,n){return this.ensure().text(t,r,e,n),this}rect(t,r,e,n,i){return this.ensure().rect(t,r,e,n,i),this}line(t,r,e,n,i){return this.ensure().line(t,r,e,n,i),this}circle(t,r,e,n){return this.ensure().circle(t,r,e,n),this}image(t,r,e,n){return this.ensure().image(t,r,e,n),this}link(t,r,e,n,i){return this.ensure().link(t,r,e,n,i),this}table(t,r,e,n){return this.ensure().table(t,r,e,n),this}ensure(){if(!this.cur)this.page();return this.cur}build(){let t=new x,r=[0],e=0;t.l("%PDF-1.4").l("%µµµµ");let n=new Set;this.pages.forEach((l)=>l.f.forEach((g)=>n.add(g)));let i=Array.from(n),o={};for(let l of i){let g=++e;o[l]=g,r[g]=t.size(),t.l(`${g} 0 obj`).l(`<</Type/Font/Subtype/Type1/BaseFont/${l}>>`).l("endobj")}let h=[],c=[],f=[];for(let l of this.pages){let g=[];for(let p of l.imgs){let w=++e;g.push(w),r[w]=t.size();let v=String.fromCharCode(...p.d);t.l(`${w} 0 obj`).l(`<</Type/XObject/Subtype/Image/Width ${p.w}/Height ${p.h}/ColorSpace/DeviceRGB/BitsPerComponent 8/Filter/DCTDecode/Length ${p.d.length}>>`).l("stream").w(v).l("").l("endstream").l("endobj")}f.push(g);let $=l.c.join(`
3
+ `),k=new TextEncoder().encode($).length,y=++e;h.push(y),r[y]=t.size(),t.l(`${y} 0 obj`).l(`<</Length ${k}>>`).l("stream").w($).l("").l("endstream").l("endobj");let F=[];for(let p of l.links){let w=++e;F.push(w),r[w]=t.size(),t.l(`${w} 0 obj`).l(`<</Type/Annot/Subtype/Link/Rect[${p.x} ${p.y} ${p.x+p.w} ${p.y+p.h}]/Border[0 0 0]/A<</Type/Action/S/URI/URI(${p.url})>>>>`).l("endobj")}c.push(F)}let m=++e,b=e+1,a=this.pages.map((l,g)=>b+g);r[m]=t.size(),t.l(`${m} 0 obj`).l(`<</Type/Pages/Kids[${a.map((l)=>`${l} 0 R`).join(" ")}]/Count ${a.length}>>`).l("endobj");for(let l=0;l<this.pages.length;l++){let g=this.pages[l],$=++e,k=Array.from(g.f).map((p)=>`/${p.replace("-","")} ${o[p]} 0 R`).join(""),y=g.imgs.map((p,w)=>`/${p.id} ${f[l][w]} 0 R`).join(""),F=c[l].length?`/Annots[${c[l].map((p)=>`${p} 0 R`).join(" ")}]`:"";r[$]=t.size(),t.l(`${$} 0 obj`).l(`<</Type/Page/Parent ${m} 0 R/MediaBox[0 0 ${g.w} ${g.h}]/Contents ${h[l]} 0 R/Resources<<${k?`/Font<<${k}>>`:""}${y?`/XObject<<${y}>>`:""}>>${F}>>`).l("endobj")}let u=0;if(this.meta){u=++e,r[u]=t.size();let l=new Date,g=`D:${l.getFullYear()}${String(l.getMonth()+1).padStart(2,"0")}${String(l.getDate()).padStart(2,"0")}${String(l.getHours()).padStart(2,"0")}${String(l.getMinutes()).padStart(2,"0")}${String(l.getSeconds()).padStart(2,"0")}`,$=this.meta;t.l(`${u} 0 obj`).l(`<<${$.title?`/Title(${C($.title)})`:""}${$.author?`/Author(${C($.author)})`:""}${$.subject?`/Subject(${C($.subject)})`:""}${$.keywords?`/Keywords(${C($.keywords)})`:""}${$.creator?`/Creator(${C($.creator)})`:""}/Producer(podpdf)/CreationDate(${g})>>`).l("endobj")}let d=++e;r[d]=t.size(),t.l(`${d} 0 obj`).l(`<</Type/Catalog/Pages ${m} 0 R>>`).l("endobj");let B=t.size();t.l("xref").l(`0 ${e+1}`).l("0000000000 65535 f ");for(let l=1;l<=e;l++)t.l(`${r[l].toString().padStart(10,"0")} 00000 n `);return t.l("trailer").l(`<</Size ${e+1}/Root ${d} 0 R${u?`/Info ${u} 0 R`:""}>>`).l("startxref").l(B.toString()).l("%%EOF"),t.out()}async save(t){let r=this.build();if(typeof Bun<"u")await Bun.write(t,r);else{let{writeFile:e}=await import("fs/promises");await e(t,r)}}}var Z=(t)=>new R(t);export{Z as pdf,T as SIZES,R as PDF};
package/dist/plus.d.ts ADDED
@@ -0,0 +1,84 @@
1
+ export type Color = string | [number, number, number];
2
+ export type Align = 'left' | 'center' | 'right';
3
+ export type Weight = 'normal' | 'bold' | 'italic' | 'bolditalic';
4
+ export interface Size {
5
+ width: number;
6
+ height: number;
7
+ }
8
+ export interface TextOpts {
9
+ size?: number;
10
+ color?: Color;
11
+ align?: Align;
12
+ weight?: Weight;
13
+ maxWidth?: number;
14
+ font?: string;
15
+ }
16
+ export interface RectOpts {
17
+ fill?: Color;
18
+ stroke?: Color;
19
+ lineWidth?: number;
20
+ radius?: number;
21
+ }
22
+ export interface LineOpts {
23
+ color?: Color;
24
+ width?: number;
25
+ dash?: number[];
26
+ }
27
+ export interface CircleOpts {
28
+ fill?: Color;
29
+ stroke?: Color;
30
+ lineWidth?: number;
31
+ }
32
+ export interface ImageOpts {
33
+ width?: number;
34
+ height?: number;
35
+ }
36
+ export interface LinkOpts {
37
+ underline?: boolean;
38
+ color?: Color;
39
+ }
40
+ export interface TableCol {
41
+ header: string;
42
+ width?: number;
43
+ align?: Align;
44
+ }
45
+ export interface TableOpts {
46
+ columns: TableCol[];
47
+ headerBg?: Color;
48
+ headerColor?: Color;
49
+ borderColor?: Color;
50
+ fontSize?: number;
51
+ padding?: number;
52
+ }
53
+ export interface PDFMetadata {
54
+ title?: string;
55
+ author?: string;
56
+ subject?: string;
57
+ keywords?: string;
58
+ creator?: string;
59
+ }
60
+ export declare const SIZES: Record<string, Size>;
61
+ export declare class PDFPlus {
62
+ private pages;
63
+ private cur;
64
+ private sz;
65
+ private meta?;
66
+ private customFonts;
67
+ constructor(s?: Size | keyof typeof SIZES);
68
+ metadata(m: PDFMetadata): this;
69
+ registerFont(name: string, data: Uint8Array): this;
70
+ page(s?: Size | keyof typeof SIZES): this;
71
+ text(t: string, x: number, y: number, o?: TextOpts): this;
72
+ rect(x: number, y: number, w: number, h: number, o?: RectOpts): this;
73
+ line(x1: number, y1: number, x2: number, y2: number, o?: LineOpts): this;
74
+ circle(cx: number, cy: number, r: number, o?: CircleOpts): this;
75
+ image(d: Uint8Array, x: number, y: number, o?: ImageOpts): this;
76
+ link(t: string, url: string, x: number, y: number, o?: LinkOpts): this;
77
+ table(data: string[][], x: number, y: number, o: TableOpts): this;
78
+ imagePng(d: Uint8Array, x: number, y: number, o?: ImageOpts): Promise<this>;
79
+ private ensure;
80
+ build(): Uint8Array;
81
+ save(path: string): Promise<void>;
82
+ }
83
+ export declare const pdfPlus: (s?: Size | keyof typeof SIZES) => PDFPlus;
84
+ //# sourceMappingURL=plus.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plus.d.ts","sourceRoot":"","sources":["../src/plus.ts"],"names":[],"mappings":"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"}
package/dist/plus.js ADDED
@@ -0,0 +1,3 @@
1
+ import{createRequire as e}from"node:module";var x=Object.create;var{getPrototypeOf:t,defineProperty:I,getOwnPropertyNames:c}=Object;var p=Object.prototype.hasOwnProperty;var g=(q,K,L)=>{L=q!=null?x(t(q)):{};let Q=K||!q||!q.__esModule?I(L,"default",{value:q,enumerable:!0}):L;for(let U of c(q))if(!p.call(Q,U))I(Q,U,{get:()=>q[U],enumerable:!0});return Q};var b=e(import.meta.url);var m={A4:{width:595,height:842},A3:{width:842,height:1191},A5:{width:420,height:595},LETTER:{width:612,height:792}},h={helvetica:{normal:"Helvetica",bold:"Helvetica-Bold",italic:"Helvetica-Oblique",bolditalic:"Helvetica-BoldOblique"},times:{normal:"Times-Roman",bold:"Times-Bold",italic:"Times-Italic",bolditalic:"Times-BoldItalic"},courier:{normal:"Courier",bold:"Courier-Bold",italic:"Courier-Oblique",bolditalic:"Courier-BoldOblique"}},l=(q)=>{if(Array.isArray(q))return q;let K=q.replace("#","");if(K.length===3)return[parseInt(K[0]+K[0],16)/255,parseInt(K[1]+K[1],16)/255,parseInt(K[2]+K[2],16)/255];return[parseInt(K.slice(0,2),16)/255,parseInt(K.slice(2,4),16)/255,parseInt(K.slice(4,6),16)/255]},T=(q)=>{let[K,L,Q]=l(q);return`${K.toFixed(3)} ${L.toFixed(3)} ${Q.toFixed(3)} rg`},u=(q)=>{let[K,L,Q]=l(q);return`${K.toFixed(3)} ${L.toFixed(3)} ${Q.toFixed(3)} RG`},F=(q)=>q.replace(/\\/g,"\\\\").replace(/\(/g,"\\(").replace(/\)/g,"\\)"),W=(q)=>Number.isInteger(q)?q.toString():q.toFixed(2),k=(q,K)=>q.length*K*0.52,n=(q)=>{if(q[0]!==137||q[1]!==80||q[2]!==78||q[3]!==71)return null;let K=8,L=0,Q=0,U=0,V=[];while(K<q.length){let B=q[K]<<24|q[K+1]<<16|q[K+2]<<8|q[K+3],z=String.fromCharCode(q[K+4],q[K+5],q[K+6],q[K+7]);if(z==="IHDR")L=q[K+8]<<24|q[K+9]<<16|q[K+10]<<8|q[K+11],Q=q[K+12]<<24|q[K+13]<<16|q[K+14]<<8|q[K+15],U=q[K+17];else if(z==="IDAT")V.push(q.slice(K+8,K+8+B));else if(z==="IEND")break;K+=12+B}if(!L||!V.length)return null;let X=V.reduce((B,z)=>B+z.length,0),C=new Uint8Array(X),Z=0;for(let B of V)C.set(B,Z),Z+=B.length;return{w:L,h:Q,colorType:U,idat:C}},i=(q,K,L,Q)=>{let U=Q===6?4:Q===2?3:Q===4?2:1,V=K*U+1,X=new Uint8Array(K*L*3),C=Q===6||Q===4?new Uint8Array(K*L):void 0,Z=(B,z,_)=>{let Y=B+z-_,J=Math.abs(Y-B),D=Math.abs(Y-z),N=Math.abs(Y-_);return J<=D&&J<=N?B:D<=N?z:_};for(let B=0;B<L;B++){let z=q[B*V];for(let _=0;_<K*U;_++){let Y=B*V+1+_,J=_>=U?q[Y-U]:0,D=B>0?q[(B-1)*V+1+_]:0,N=_>=U&&B>0?q[(B-1)*V+1+_-U]:0;if(z===1)q[Y]=q[Y]+J&255;else if(z===2)q[Y]=q[Y]+D&255;else if(z===3)q[Y]=q[Y]+Math.floor((J+D)/2)&255;else if(z===4)q[Y]=q[Y]+Z(J,D,N)&255}for(let _=0;_<K;_++){let Y=B*V+1+_*U,J=(B*K+_)*3;if(Q===6){if(X[J]=q[Y],X[J+1]=q[Y+1],X[J+2]=q[Y+2],C)C[B*K+_]=q[Y+3]}else if(Q===4){if(X[J]=X[J+1]=X[J+2]=q[Y],C)C[B*K+_]=q[Y+1]}else if(Q===2)X[J]=q[Y],X[J+1]=q[Y+1],X[J+2]=q[Y+2];else X[J]=X[J+1]=X[J+2]=q[Y]}}return{w:K,h:L,rgb:X,alpha:C}},r=(q)=>{let K=(O)=>q[O]<<8|q[O+1],L=(O)=>{let $=K(O);return $>32767?$-65536:$},Q=(O)=>q[O]<<24|q[O+1]<<16|q[O+2]<<8|q[O+3],U=K(4),V={};for(let O=0;O<U;O++){let $=12+O*16;V[String.fromCharCode(q[$],q[$+1],q[$+2],q[$+3])]={offset:Q($+8),length:Q($+12)}}if(!V.head||!V.hhea||!V.hmtx||!V.maxp)return null;let X=V.head.offset,C=K(X+18),Z=[L(X+36),L(X+38),L(X+40),L(X+42)],B=V.hhea.offset,z=L(B+4),_=L(B+6),Y=K(B+34),J=V.hmtx.offset,D=[];for(let O=0;O<Math.min(Y,256);O++)D.push(K(J+O*4));let N="CustomFont";if(V.name){let O=V.name.offset,$=K(O+2),M=O+K(O+4);for(let H=0;H<$;H++){let E=O+6+H*12;if(K(E+6)===6){N=Array.from(q.slice(M+K(E+10),M+K(E+10)+K(E+8))).filter((G)=>G>31&&G<127).map((G)=>String.fromCharCode(G)).join("");break}}}return{name:N.replace(/[^a-zA-Z0-9]/g,""),unitsPerEm:C,ascent:z,descent:_,bbox:Z,widths:D,data:q}};class f{c=[];s=0;e=new TextEncoder;w(q){let K=typeof q==="string"?this.e.encode(q):q;return this.c.push(K),this.s+=K.length,this}l(q){return this.w(q+`
2
+ `)}size(){return this.s}out(){let q=new Uint8Array(this.s),K=0;for(let L of this.c)q.set(L,K),K+=L.length;return q}}class w{w;h;c=[];f=new Set;imgs=[];links=[];ic=0;constructor(q){this.w=q.width,this.h=q.height}text(q,K,L,Q={}){let U=Q.size??12,V=Q.weight??"normal",X=Q.color??"#000",C=Q.align??"left",Z=Q.font&&h[Q.font]?Q.font:"helvetica",B=h[Z][V];this.f.add(B);let z=this.h-L,_=K,Y=Q.maxWidth?this.wrap(q,Q.maxWidth,U):[q];for(let J of Y)_=C==="center"?K-k(J,U)/2:C==="right"?K-k(J,U):K,this.c.push("q","BT",T(X),`/${B.replace("-","")} ${U} Tf`,`${W(_)} ${W(z)} Td`,`(${F(J)}) Tj`,"ET","Q"),z-=U*1.2;return this}rect(q,K,L,Q,U={}){let V=this.h-K-Q;if(this.c.push("q"),U.radius&&U.radius>0){let X=Math.min(U.radius,L/2,Q/2);this.c.push(`${W(q+X)} ${W(V)} m`,`${W(q+L-X)} ${W(V)} l`,`${W(q+L)} ${W(V)} ${W(q+L)} ${W(V+X)} y`,`${W(q+L)} ${W(V+Q-X)} l`,`${W(q+L)} ${W(V+Q)} ${W(q+L-X)} ${W(V+Q)} y`,`${W(q+X)} ${W(V+Q)} l`,`${W(q)} ${W(V+Q)} ${W(q)} ${W(V+Q-X)} y`,`${W(q)} ${W(V+X)} l`,`${W(q)} ${W(V)} ${W(q+X)} ${W(V)} y`,"h")}else this.c.push(`${W(q)} ${W(V)} ${W(L)} ${W(Q)} re`);if(U.fill)this.c.push(T(U.fill)),this.c.push(U.stroke?"B":"f");if(U.stroke){if(this.c.push(u(U.stroke)),U.lineWidth)this.c.push(`${U.lineWidth} w`);if(!U.fill)this.c.push("S")}return this.c.push("Q"),this}line(q,K,L,Q,U={}){if(this.c.push("q"),U.color)this.c.push(u(U.color));if(U.width)this.c.push(`${U.width} w`);if(U.dash)this.c.push(`[${U.dash.join(" ")}] 0 d`);return this.c.push(`${W(q)} ${W(this.h-K)} m`,`${W(L)} ${W(this.h-Q)} l`,"S","Q"),this}circle(q,K,L,Q={}){let U=this.h-K;if(this.c.push("q"),this.c.push(`${W(q+L)} ${W(U)} m`,`${W(q+L)} ${W(U+L*0.5523)} ${W(q+L*0.5523)} ${W(U+L)} ${W(q)} ${W(U+L)} c`,`${W(q-L*0.5523)} ${W(U+L)} ${W(q-L)} ${W(U+L*0.5523)} ${W(q-L)} ${W(U)} c`,`${W(q-L*0.5523)} ${W(U-L)} ${W(q-L)} ${W(U-L*0.5523)} ${W(q)} ${W(U-L)} c`,`${W(q+L*0.5523)} ${W(U-L)} ${W(q+L)} ${W(U-L*0.5523)} ${W(q+L)} ${W(U)} c`),Q.fill)this.c.push(T(Q.fill)),this.c.push(Q.stroke?"B":"f");if(Q.stroke){if(this.c.push(u(Q.stroke)),Q.lineWidth)this.c.push(`${Q.lineWidth} w`);if(!Q.fill)this.c.push("S")}return this.c.push("Q"),this}image(q,K,L,Q={},U){let V=U||this.imgInfo(q);if(!V)return this;let X=Q.width??V.w,C=Q.height??V.h,Z=`I${++this.ic}`,B=U?"png":"jpeg";return this.imgs.push({d:q,w:V.w,h:V.h,x:K,y:this.h-L-C,id:Z,fmt:B,png:U}),this.c.push("q",`${W(X)} 0 0 ${W(C)} ${W(K)} ${W(this.h-L-C)} cm`,`/${Z} Do`,"Q"),this}link(q,K,L,Q,U={}){let V=U.color??"#00E";this.text(q,L,Q,{color:V,size:12});let C=k(q,12);if(U.underline!==!1)this.line(L,Q+2,L+C,Q+2,{color:V,width:0.5});return this.links.push({x:L,y:this.h-Q-12,w:C,h:12,url:K}),this}table(q,K,L,Q){let U=Q.padding??8,V=Q.fontSize??10,X=V+U*2,C=Q.columns.map((_,Y)=>_.width??Math.max(k(_.header,V),...q.map((J)=>k(J[Y]??"",V)))+U*2),Z=C.reduce((_,Y)=>_+Y,0),B=L;this.rect(K,B,Z,X,{fill:Q.headerBg??"#F0F0F0"});let z=K;for(let _=0;_<Q.columns.length;_++){let Y=Q.columns[_];this.text(Y.header,z+(Y.align==="center"?C[_]/2:Y.align==="right"?C[_]-U:U),B+U+V*0.8,{size:V,weight:"bold",color:Q.headerColor??"#000",align:Y.align}),z+=C[_]}B+=X;for(let _=0;_<q.length;_++){this.rect(K,B,Z,X,{fill:_%2?"#F9F9F9":"#FFF"}),z=K;for(let Y=0;Y<Q.columns.length;Y++){let J=Q.columns[Y];this.text(q[_][Y]??"",z+(J.align==="center"?C[Y]/2:J.align==="right"?C[Y]-U:U),B+U+V*0.8,{size:V,align:J.align}),z+=C[Y]}B+=X}return this.rect(K,L,Z,X*(q.length+1),{stroke:Q.borderColor??"#CCC"}),this}wrap(q,K,L){let Q=q.split(" "),U=[],V="";for(let X of Q){let C=V?`${V} ${X}`:X;if(k(C,L)<=K)V=C;else{if(V)U.push(V);V=X}}if(V)U.push(V);return U}imgInfo(q){if(q[0]===255&&q[1]===216){let K=2;while(K<q.length){if(q[K]!==255)break;let L=q[K+1];if(L>=192&&L<=207&&L!==196&&L!==200&&L!==204)return{h:q[K+5]<<8|q[K+6],w:q[K+7]<<8|q[K+8]};K+=2+(q[K+2]<<8|q[K+3])}}return null}}class y{pages=[];cur=null;sz;meta;customFonts=new Map;constructor(q="A4"){this.sz=typeof q==="string"?m[q]:q}metadata(q){return this.meta=q,this}registerFont(q,K){let L=r(K);if(L)this.customFonts.set(q,L);return this}page(q){return this.cur=new w(q?typeof q==="string"?m[q]:q:this.sz),this.pages.push(this.cur),this}text(q,K,L,Q){return this.ensure().text(q,K,L,Q),this}rect(q,K,L,Q,U){return this.ensure().rect(q,K,L,Q,U),this}line(q,K,L,Q,U){return this.ensure().line(q,K,L,Q,U),this}circle(q,K,L,Q){return this.ensure().circle(q,K,L,Q),this}image(q,K,L,Q){return this.ensure().image(q,K,L,Q),this}link(q,K,L,Q,U){return this.ensure().link(q,K,L,Q,U),this}table(q,K,L,Q){return this.ensure().table(q,K,L,Q),this}async imagePng(q,K,L,Q){let U=n(q);if(!U)return this;let V;if(typeof Bun<"u")V=Bun.inflateSync(new Uint8Array(U.idat));else{let{inflateSync:C}=await import("zlib");V=new Uint8Array(C(U.idat))}let X=i(V,U.w,U.h,U.colorType);return this.ensure().image(q,K,L,Q,X),this}ensure(){if(!this.cur)this.page();return this.cur}build(){let q=new f,K=[0],L=0;q.l("%PDF-1.4").l("%µµµµ");let Q=new Set;this.pages.forEach(($)=>$.f.forEach((M)=>Q.add(M)));let U=Array.from(Q),V={};for(let $ of U){let M=++L;V[$]=M,K[M]=q.size(),q.l(`${M} 0 obj`).l(`<</Type/Font/Subtype/Type1/BaseFont/${$}>>`).l("endobj")}let X={};for(let[$,M]of this.customFonts){let H=++L;K[H]=q.size(),q.l(`${H} 0 obj`).l(`<</Length ${M.data.length}/Length1 ${M.data.length}>>`).l("stream"),q.w(M.data).l("").l("endstream").l("endobj");let E=++L;K[E]=q.size();let G=1000/M.unitsPerEm;q.l(`${E} 0 obj`).l(`<</Type/FontDescriptor/FontName/${M.name}/Flags 32/FontBBox[${M.bbox.map((j)=>Math.round(j*G)).join(" ")}]/ItalicAngle 0/Ascent ${Math.round(M.ascent*G)}/Descent ${Math.round(M.descent*G)}/CapHeight ${Math.round(M.ascent*G*0.7)}/StemV 80/FontFile2 ${H} 0 R>>`).l("endobj");let R=++L;K[R]=q.size();let v=M.widths.slice(0,256).map((j)=>Math.round(j*G)).join(" ");q.l(`${R} 0 obj`).l(`<</Type/Font/Subtype/TrueType/BaseFont/${M.name}/FirstChar 0/LastChar 255/Widths[${v}]/FontDescriptor ${E} 0 R/Encoding/WinAnsiEncoding>>`).l("endobj"),X[$]={fontId:R,descId:E,fileId:H}}let C=[],Z=[],B=[],z=[];for(let $ of this.pages){let M=[],H=[];for(let j of $.imgs)if(j.fmt==="png"&&j.png){let A=j.png,P=0;if(A.alpha)P=++L,H.push(P),K[P]=q.size(),q.l(`${P} 0 obj`).l(`<</Type/XObject/Subtype/Image/Width ${A.w}/Height ${A.h}/ColorSpace/DeviceGray/BitsPerComponent 8/Length ${A.alpha.length}>>`).l("stream"),q.w(A.alpha).l("").l("endstream").l("endobj");let S=++L;M.push(S),K[S]=q.size(),q.l(`${S} 0 obj`).l(`<</Type/XObject/Subtype/Image/Width ${A.w}/Height ${A.h}/ColorSpace/DeviceRGB/BitsPerComponent 8${P?`/SMask ${P} 0 R`:""}/Length ${A.rgb.length}>>`).l("stream"),q.w(A.rgb).l("").l("endstream").l("endobj")}else{let A=++L;M.push(A),K[A]=q.size(),q.l(`${A} 0 obj`).l(`<</Type/XObject/Subtype/Image/Width ${j.w}/Height ${j.h}/ColorSpace/DeviceRGB/BitsPerComponent 8/Filter/DCTDecode/Length ${j.d.length}>>`).l("stream"),q.w(j.d).l("").l("endstream").l("endobj")}B.push(M),z.push(H);let E=$.c.join(`
3
+ `),G=new TextEncoder().encode(E).length,R=++L;C.push(R),K[R]=q.size(),q.l(`${R} 0 obj`).l(`<</Length ${G}>>`).l("stream").w(E).l("").l("endstream").l("endobj");let v=[];for(let j of $.links){let A=++L;v.push(A),K[A]=q.size(),q.l(`${A} 0 obj`).l(`<</Type/Annot/Subtype/Link/Rect[${j.x} ${j.y} ${j.x+j.w} ${j.y+j.h}]/Border[0 0 0]/A<</Type/Action/S/URI/URI(${j.url})>>>>`).l("endobj")}Z.push(v)}let _=++L,Y=L+1,J=this.pages.map(($,M)=>Y+M);K[_]=q.size(),q.l(`${_} 0 obj`).l(`<</Type/Pages/Kids[${J.map(($)=>`${$} 0 R`).join(" ")}]/Count ${J.length}>>`).l("endobj");for(let $=0;$<this.pages.length;$++){let M=this.pages[$],H=++L,E=Array.from(M.f).map((j)=>`/${j.replace("-","")} ${V[j]} 0 R`).join(""),G=Array.from(this.customFonts.keys()).map((j)=>`/${j} ${X[j].fontId} 0 R`).join(""),R=M.imgs.map((j,A)=>`/${j.id} ${B[$][A]} 0 R`).join(""),v=Z[$].length?`/Annots[${Z[$].map((j)=>`${j} 0 R`).join(" ")}]`:"";K[H]=q.size(),q.l(`${H} 0 obj`).l(`<</Type/Page/Parent ${_} 0 R/MediaBox[0 0 ${M.w} ${M.h}]/Contents ${C[$]} 0 R/Resources<<${E||G?`/Font<<${E}${G}>>`:""}${R?`/XObject<<${R}>>`:""}>>${v}>>`).l("endobj")}let D=0;if(this.meta){D=++L,K[D]=q.size();let $=new Date,M=`D:${$.getFullYear()}${String($.getMonth()+1).padStart(2,"0")}${String($.getDate()).padStart(2,"0")}${String($.getHours()).padStart(2,"0")}${String($.getMinutes()).padStart(2,"0")}${String($.getSeconds()).padStart(2,"0")}`,H=this.meta;q.l(`${D} 0 obj`).l(`<<${H.title?`/Title(${F(H.title)})`:""}${H.author?`/Author(${F(H.author)})`:""}${H.subject?`/Subject(${F(H.subject)})`:""}${H.keywords?`/Keywords(${F(H.keywords)})`:""}${H.creator?`/Creator(${F(H.creator)})`:""}/Producer(podpdf)/CreationDate(${M})>>`).l("endobj")}let N=++L;K[N]=q.size(),q.l(`${N} 0 obj`).l(`<</Type/Catalog/Pages ${_} 0 R>>`).l("endobj");let O=q.size();q.l("xref").l(`0 ${L+1}`).l("0000000000 65535 f ");for(let $=1;$<=L;$++)q.l(`${K[$].toString().padStart(10,"0")} 00000 n `);return q.l("trailer").l(`<</Size ${L+1}/Root ${N} 0 R${D?`/Info ${D} 0 R`:""}>>`).l("startxref").l(O.toString()).l("%%EOF"),q.out()}async save(q){let K=this.build();if(typeof Bun<"u")await Bun.write(q,K);else{let{writeFile:L}=await import("fs/promises");await L(q,K)}}}var d=(q)=>new y(q);export{d as pdfPlus,m as SIZES,y as PDFPlus};
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "podpdf",
3
- "version": "1.0.1",
4
- "description": "Ultra-fast, zero-dependency PDF generation library. 8KB minified, 5x faster than jsPDF.",
3
+ "version": "1.2.0",
4
+ "description": "Ultra-fast, zero-dependency PDF generation for Node.js, Bun & Browser. 8KB minified, 5x faster than jsPDF.",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
7
7
  "module": "dist/index.js",
@@ -10,13 +10,23 @@
10
10
  ".": {
11
11
  "import": "./dist/index.js",
12
12
  "types": "./dist/index.d.ts"
13
+ },
14
+ "./plus": {
15
+ "import": "./dist/plus.js",
16
+ "types": "./dist/plus.d.ts"
17
+ },
18
+ "./browser": {
19
+ "import": "./dist/browser.js",
20
+ "types": "./dist/browser.d.ts"
13
21
  }
14
22
  },
15
23
  "files": [
16
24
  "dist"
17
25
  ],
18
26
  "scripts": {
19
- "build": "bun build src/index.ts --outdir dist --target node --minify && bun run build:types",
27
+ "build": "bun run build:node && bun run build:browser && bun run build:types",
28
+ "build:node": "bun build src/index.ts src/plus.ts --outdir dist --target node --minify",
29
+ "build:browser": "bun build src/browser.ts --outdir dist --target browser --minify",
20
30
  "build:types": "tsc --emitDeclarationOnly",
21
31
  "dev": "bun --watch src/index.ts",
22
32
  "test": "bun test/test.ts",
@@ -35,7 +45,10 @@
35
45
  "zero-dependency",
36
46
  "fast",
37
47
  "lightweight",
38
- "minimal"
48
+ "minimal",
49
+ "browser",
50
+ "browser-pdf",
51
+ "client-side"
39
52
  ],
40
53
  "author": "",
41
54
  "license": "MIT",