deno.land / x / skia_canvas@0.5.8 / src / pdfdocument.ts

pdfdocument.ts
نووسراو ببینە
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
import { CanvasRenderingContext2D } from "./context2d.ts";import ffi, { cstr, getBuffer } from "./ffi.ts";
const { sk_pdf_begin_page, sk_pdf_destroy, sk_pdf_new, sk_pdf_get_buffer, sk_pdf_write_file, sk_pdf_end_page, sk_data_free,} = ffi;
const PDF_DOCUMENT_FINALIZER = new FinalizationRegistry( (ptr: Deno.PointerValue) => { sk_pdf_destroy(ptr); },);
const SK_DATA_FINALIZER = new FinalizationRegistry( (ptr: Deno.PointerValue) => { sk_data_free(ptr); },);
export interface PdfMetadata { title?: string; author?: string; subject?: string; keywords?: string; creator?: string; producer?: string; creation?: Date; modified?: Date; pdfa?: boolean; encodingQuality?: number;}
export interface Rect { x: number; y: number; w: number; h: number;}
const DATE_TIME_SIZE = 2 + 2 + 1 + 1 + 1 + 1 + 1 + 1;
const OUT_SIZE = new Uint32Array(1);const OUT_SIZE_PTR = new Uint8Array(OUT_SIZE.buffer);const OUT_DATA = new BigUint64Array(1);const OUT_DATA_PTR = new Uint8Array(OUT_DATA.buffer);
function dateToSkTime(date: Date) { const buffer = new Uint8Array(DATE_TIME_SIZE); const view = new DataView(buffer.buffer); view.setUint16(2, date.getUTCFullYear(), true); view.setUint8(4, date.getUTCMonth() + 1); view.setUint8(5, date.getUTCDay()); return buffer;}
export class PdfRenderingContext2D extends CanvasRenderingContext2D { // @ts-expect-error typescript error declare canvas!: PdfDocument;
constructor( canvas: PdfDocument, ptr: Deno.PointerValue, public width: number, public height: number, ) { // deno-lint-ignore no-explicit-any super(canvas as any, ptr); }}
const _ptr = Symbol("[[ptr]]");
/** * Create a new PDF document to draw using Canvas 2D API. */export class PdfDocument { [_ptr]: Deno.PointerValue;
constructor(options: PdfMetadata = {}) { this[_ptr] = sk_pdf_new( cstr(options.title ?? ""), cstr(options.author ?? ""), cstr(options.subject ?? ""), cstr(options.keywords ?? ""), cstr(options.creator ?? ""), cstr(options.producer ?? ""), options.creation ? dateToSkTime(options.creation) : new Uint8Array(DATE_TIME_SIZE), options.modified ? dateToSkTime(options.modified) : new Uint8Array(DATE_TIME_SIZE), options.pdfa ?? false, options.encodingQuality ?? 0, ); PDF_DOCUMENT_FINALIZER.register(this, this[_ptr]); }
/** * Creates a new page and returns a 2D rendering context for drawing on it. * The context extends CanvasRenderingContext2D so it has same API. * * You must not use the context after calling endPage. */ newPage(w: number, h: number, contentRect?: Rect): PdfRenderingContext2D { const ptr = sk_pdf_begin_page( this[_ptr], w, h, ...(contentRect ? [contentRect.x, contentRect.y, contentRect.w, contentRect.h] : [0, 0, w, h]) as [number, number, number, number], ); if (!ptr) { throw new Error("Failed to create new page"); } return new PdfRenderingContext2D(this, ptr, w, h); }
/** Writes the page into internal stream and destroys */ endPage() { sk_pdf_end_page(this[_ptr]); }
/** Saves PDF to the file and closes the stream. Changes cannot be made to PDF after this. */ save(path: string) { if (!sk_pdf_write_file(this[_ptr], cstr(path))) { throw new Error("Failed to save PDF"); } }
/** Encodes the PDF into a buffer and closes the stream. Changes cannot be made to PDF after this. */ encode(): Uint8Array { const skdata = sk_pdf_get_buffer(this[_ptr], OUT_DATA_PTR, OUT_SIZE_PTR); if (!skdata) { throw new Error("Failed to encode PDF"); } const size = OUT_SIZE[0]; const ptr = OUT_DATA[0]; const buffer = new Uint8Array( getBuffer(Deno.UnsafePointer.create(ptr), 0, size), ); SK_DATA_FINALIZER.register(buffer, skdata); return buffer; }}
skia_canvas

Version Info

Tagged at
8 months ago