pdf-oxide 0.3.36 → 0.3.38
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/lib/builders/document-builder.d.ts +199 -0
- package/lib/builders/document-builder.js +434 -0
- package/lib/builders/index.d.ts +3 -2
- package/lib/builders/index.js +3 -2
- package/lib/document-editor.d.ts +57 -0
- package/lib/document-editor.js +184 -0
- package/lib/errors.js +3 -4
- package/lib/form-field-manager.js +3 -1
- package/lib/index.d.ts +40 -6
- package/lib/index.js +253 -90
- package/lib/managers/accessibility-manager.js +19 -8
- package/lib/managers/annotation-manager.js +9 -9
- package/lib/managers/barcode-manager.js +18 -7
- package/lib/managers/batch-manager.js +2 -5
- package/lib/managers/cache-manager.js +1 -3
- package/lib/managers/compliance-manager.js +58 -19
- package/lib/managers/document-utility-manager.js +6 -6
- package/lib/managers/dom-pdf-creator.js +9 -9
- package/lib/managers/enterprise-manager.js +4 -1
- package/lib/managers/extended-managers.js +8 -1
- package/lib/managers/extraction-manager.js +7 -2
- package/lib/managers/final-utilities.d.ts +3 -3
- package/lib/managers/final-utilities.js +9 -4
- package/lib/managers/hybrid-ml-advanced.js +22 -6
- package/lib/managers/index.d.ts +22 -22
- package/lib/managers/index.js +23 -23
- package/lib/managers/layer-manager.js +20 -21
- package/lib/managers/ocr-manager.d.ts +2 -2
- package/lib/managers/ocr-manager.js +7 -7
- package/lib/managers/optimization-manager.js +24 -4
- package/lib/managers/page-manager.js +5 -6
- package/lib/managers/pattern-detection.d.ts +1 -1
- package/lib/managers/pattern-detection.js +4 -6
- package/lib/managers/search-manager.js +3 -3
- package/lib/managers/signature-manager.js +149 -40
- package/lib/managers/streams.js +8 -2
- package/lib/managers/xfa-manager.js +69 -19
- package/lib/native-loader.d.ts +7 -0
- package/lib/native-loader.js +62 -0
- package/lib/native.d.ts +16 -0
- package/lib/native.js +69 -0
- package/lib/pdf-creator-manager.js +4 -1
- package/lib/result-accessors-manager.js +3 -1
- package/lib/timestamp.d.ts +54 -0
- package/lib/timestamp.js +115 -0
- package/lib/tsa-client.d.ts +44 -0
- package/lib/tsa-client.js +67 -0
- package/lib/types/common.d.ts +1 -1
- package/lib/types/index.d.ts +1 -1
- package/lib/types/index.js +1 -1
- package/lib/types/manager-types.js +4 -2
- package/lib/workers/index.d.ts +1 -1
- package/lib/workers/pool.js +2 -4
- package/package.json +16 -10
- package/prebuilds/darwin-arm64/pdf_oxide.node +0 -0
- package/prebuilds/darwin-x64/pdf_oxide.node +0 -0
- package/prebuilds/linux-arm64/pdf_oxide.node +0 -0
- package/prebuilds/linux-x64/pdf_oxide.node +0 -0
- package/prebuilds/win32-x64/pdf_oxide.node +0 -0
|
@@ -0,0 +1,199 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Fluent document builder — the programmatic multi-page construction API
|
|
3
|
+
* exposed through the C FFI.
|
|
4
|
+
*
|
|
5
|
+
* Mirrors the Python / WASM / C# / Go equivalents. The same handle-lifetime
|
|
6
|
+
* contract applies: terminal methods (`build`, `save`, `saveEncrypted`,
|
|
7
|
+
* `toBytesEncrypted`) CONSUME the builder, and only one `PageBuilder` may
|
|
8
|
+
* be open at a time.
|
|
9
|
+
*
|
|
10
|
+
* @example
|
|
11
|
+
* ```typescript
|
|
12
|
+
* import { DocumentBuilder, EmbeddedFont } from 'pdf-oxide';
|
|
13
|
+
*
|
|
14
|
+
* const font = EmbeddedFont.fromFile('DejaVuSans.ttf');
|
|
15
|
+
* const builder = DocumentBuilder.create()
|
|
16
|
+
* .title('Hello')
|
|
17
|
+
* .registerEmbeddedFont('DejaVu', font); // consumes `font`
|
|
18
|
+
* builder.a4Page()
|
|
19
|
+
* .font('DejaVu', 12)
|
|
20
|
+
* .at(72, 720).text('Привет, мир!')
|
|
21
|
+
* .at(72, 700).text('Καλημέρα κόσμε')
|
|
22
|
+
* .done();
|
|
23
|
+
* const bytes = builder.build(); // consumes the builder
|
|
24
|
+
* ```
|
|
25
|
+
*/
|
|
26
|
+
/**
|
|
27
|
+
* TTF/OTF font handle registerable with {@link DocumentBuilder}. Single-use:
|
|
28
|
+
* after `registerEmbeddedFont` the native handle is moved into the builder
|
|
29
|
+
* and this object becomes disposed.
|
|
30
|
+
*/
|
|
31
|
+
export declare class EmbeddedFont {
|
|
32
|
+
private _handle;
|
|
33
|
+
private _consumed;
|
|
34
|
+
private constructor();
|
|
35
|
+
/** Load a TTF / OTF font from disk. */
|
|
36
|
+
static fromFile(path: string): EmbeddedFont;
|
|
37
|
+
/** Load a font from a byte buffer; pass `name` to override the PostScript name. */
|
|
38
|
+
static fromBytes(data: Uint8Array | Buffer, name?: string): EmbeddedFont;
|
|
39
|
+
/** @internal — used by {@link DocumentBuilder.registerEmbeddedFont} */
|
|
40
|
+
get handle(): unknown;
|
|
41
|
+
/** @internal — called by the builder after the FFI transfers ownership. */
|
|
42
|
+
markConsumed(): void;
|
|
43
|
+
/** Release the native font handle if it hasn't been consumed. */
|
|
44
|
+
close(): void;
|
|
45
|
+
/** Symbol.dispose support for `using` declarations. */
|
|
46
|
+
[Symbol.dispose](): void;
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Fluent top-level API for multi-page PDF construction.
|
|
50
|
+
* Use {@link DocumentBuilder.create} to start a new builder.
|
|
51
|
+
*/
|
|
52
|
+
export declare class DocumentBuilder {
|
|
53
|
+
private _handle;
|
|
54
|
+
private _consumed;
|
|
55
|
+
private _openPage;
|
|
56
|
+
private constructor();
|
|
57
|
+
/** Create a fresh empty builder. */
|
|
58
|
+
static create(): DocumentBuilder;
|
|
59
|
+
/** @internal — used by PageBuilder.done */
|
|
60
|
+
clearOpenPage(): void;
|
|
61
|
+
private checkUsable;
|
|
62
|
+
/** Set the document title. */
|
|
63
|
+
title(title: string): this;
|
|
64
|
+
/** Set the document author. */
|
|
65
|
+
author(author: string): this;
|
|
66
|
+
/** Set the document subject. */
|
|
67
|
+
subject(subject: string): this;
|
|
68
|
+
/** Set the document keywords (comma-separated per PDF convention). */
|
|
69
|
+
keywords(keywords: string): this;
|
|
70
|
+
/** Set the creator application name. */
|
|
71
|
+
creator(creator: string): this;
|
|
72
|
+
/**
|
|
73
|
+
* Register a TTF / OTF font under `name`. CONSUMES `font` on success —
|
|
74
|
+
* do not call `close()` on the font afterwards.
|
|
75
|
+
*/
|
|
76
|
+
registerEmbeddedFont(name: string, font: EmbeddedFont): this;
|
|
77
|
+
/** Start a new A4 page. Only one page may be outstanding per builder. */
|
|
78
|
+
a4Page(): PageBuilder;
|
|
79
|
+
/** Start a new US Letter page. */
|
|
80
|
+
letterPage(): PageBuilder;
|
|
81
|
+
/** Start a page with custom dimensions in PDF points (72 pt = 1 inch). */
|
|
82
|
+
page(width: number, height: number): PageBuilder;
|
|
83
|
+
private consumeHandle;
|
|
84
|
+
/** Build the PDF and return the bytes. CONSUMES the builder. */
|
|
85
|
+
build(): Buffer;
|
|
86
|
+
/** Save the PDF to a file. CONSUMES the builder. */
|
|
87
|
+
save(path: string): void;
|
|
88
|
+
/** Save the PDF with AES-256 encryption. CONSUMES the builder. */
|
|
89
|
+
saveEncrypted(path: string, userPassword: string, ownerPassword: string): void;
|
|
90
|
+
/** Return the PDF as encrypted bytes (AES-256). CONSUMES the builder. */
|
|
91
|
+
toBytesEncrypted(userPassword: string, ownerPassword: string): Buffer;
|
|
92
|
+
/** Release native resources if the builder wasn't consumed. */
|
|
93
|
+
close(): void;
|
|
94
|
+
/** Symbol.dispose support for `using` declarations. */
|
|
95
|
+
[Symbol.dispose](): void;
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Fluent per-page builder returned by `DocumentBuilder.a4Page` etc.
|
|
99
|
+
* Single-use — `done()` commits the page and invalidates this builder.
|
|
100
|
+
*/
|
|
101
|
+
export declare class PageBuilder {
|
|
102
|
+
private _parent;
|
|
103
|
+
private _handle;
|
|
104
|
+
private _done;
|
|
105
|
+
/** @internal — constructed by DocumentBuilder */
|
|
106
|
+
constructor(parent: DocumentBuilder, handle: unknown);
|
|
107
|
+
private h;
|
|
108
|
+
/** Set font + size for subsequent text. */
|
|
109
|
+
font(name: string, size: number): this;
|
|
110
|
+
/** Move the cursor to absolute coordinates. */
|
|
111
|
+
at(x: number, y: number): this;
|
|
112
|
+
/** Emit a line of text at the current cursor position. */
|
|
113
|
+
text(text: string): this;
|
|
114
|
+
/** Emit a heading (level 1-6). */
|
|
115
|
+
heading(level: number, text: string): this;
|
|
116
|
+
/** Emit a paragraph with automatic line wrapping. */
|
|
117
|
+
paragraph(text: string): this;
|
|
118
|
+
/** Advance the cursor by the given number of points. */
|
|
119
|
+
space(points: number): this;
|
|
120
|
+
/** Draw a horizontal rule across the page. */
|
|
121
|
+
horizontalRule(): this;
|
|
122
|
+
/** Attach a URL link to the previous text element. */
|
|
123
|
+
linkUrl(url: string): this;
|
|
124
|
+
/** Link the previous text to an internal page (0-based). */
|
|
125
|
+
linkPage(pageIndex: number): this;
|
|
126
|
+
/** Link the previous text to a named destination. */
|
|
127
|
+
linkNamed(destination: string): this;
|
|
128
|
+
/** Highlight the previous text with an RGB colour (channels 0-1). */
|
|
129
|
+
highlight(r: number, g: number, b: number): this;
|
|
130
|
+
/** Underline the previous text. */
|
|
131
|
+
underline(r: number, g: number, b: number): this;
|
|
132
|
+
/** Strike through the previous text. */
|
|
133
|
+
strikeout(r: number, g: number, b: number): this;
|
|
134
|
+
/** Squiggly-underline the previous text. */
|
|
135
|
+
squiggly(r: number, g: number, b: number): this;
|
|
136
|
+
/** Attach a sticky-note annotation to the previous text. */
|
|
137
|
+
stickyNote(text: string): this;
|
|
138
|
+
/** Place a sticky-note at an absolute position. */
|
|
139
|
+
stickyNoteAt(x: number, y: number, text: string): this;
|
|
140
|
+
/** Apply a text watermark to the page. */
|
|
141
|
+
watermark(text: string): this;
|
|
142
|
+
/** Apply the standard "CONFIDENTIAL" diagonal watermark. */
|
|
143
|
+
watermarkConfidential(): this;
|
|
144
|
+
/** Apply the standard "DRAFT" diagonal watermark. */
|
|
145
|
+
watermarkDraft(): this;
|
|
146
|
+
/**
|
|
147
|
+
* Attach a standard stamp annotation at the cursor (150×50 default).
|
|
148
|
+
* `typeName` matches the PDF spec's standard stamps (Approved,
|
|
149
|
+
* NotApproved, Draft, Confidential, Final, Experimental, Expired,
|
|
150
|
+
* ForPublicRelease, NotForPublicRelease, AsIs, Sold, Departmental,
|
|
151
|
+
* ForComment, TopSecret) — any other name becomes a custom stamp.
|
|
152
|
+
*/
|
|
153
|
+
stamp(typeName: string): this;
|
|
154
|
+
/** Place a free-flowing text annotation inside the rectangle (x, y, w, h). */
|
|
155
|
+
freeText(x: number, y: number, w: number, h: number, text: string): this;
|
|
156
|
+
/**
|
|
157
|
+
* Add a single-line text form field at the rectangle (x, y, w, h).
|
|
158
|
+
* `name` is the unique field identifier used for form submission;
|
|
159
|
+
* `defaultValue` is the initial text (pass undefined for blank).
|
|
160
|
+
*/
|
|
161
|
+
textField(name: string, x: number, y: number, w: number, h: number, defaultValue?: string): this;
|
|
162
|
+
/**
|
|
163
|
+
* Add a checkbox form field at the rectangle (x, y, w, h).
|
|
164
|
+
* `checked` sets the initial state.
|
|
165
|
+
*/
|
|
166
|
+
checkbox(name: string, x: number, y: number, w: number, h: number, checked?: boolean): this;
|
|
167
|
+
/**
|
|
168
|
+
* Add a dropdown combo-box form field. `options` are the user-
|
|
169
|
+
* visible choices; `selected` picks the initial value.
|
|
170
|
+
*/
|
|
171
|
+
comboBox(name: string, x: number, y: number, w: number, h: number, options: string[], selected?: string): this;
|
|
172
|
+
/**
|
|
173
|
+
* Add a radio-button group. `buttons` is an array of
|
|
174
|
+
* `[exportValue, x, y, w, h]` tuples — one per option. `selected`
|
|
175
|
+
* picks the initial value by export value.
|
|
176
|
+
*/
|
|
177
|
+
radioGroup(name: string, buttons: Array<[string, number, number, number, number]>, selected?: string): this;
|
|
178
|
+
/** Add a clickable push button with a visible caption. */
|
|
179
|
+
pushButton(name: string, x: number, y: number, w: number, h: number, caption: string): this;
|
|
180
|
+
/** Draw a stroked rectangle outline (1pt black). */
|
|
181
|
+
rect(x: number, y: number, w: number, h: number): this;
|
|
182
|
+
/** Draw a filled rectangle in RGB colour (channels 0–1). */
|
|
183
|
+
filledRect(x: number, y: number, w: number, h: number, r: number, g: number, b: number): this;
|
|
184
|
+
/** Draw a line from `(x1, y1)` to `(x2, y2)` with 1pt black stroke. */
|
|
185
|
+
line(x1: number, y1: number, x2: number, y2: number): this;
|
|
186
|
+
/**
|
|
187
|
+
* Commit the page's buffered operations to the parent builder and
|
|
188
|
+
* return the parent for chaining. After `done()` this PageBuilder is
|
|
189
|
+
* invalid.
|
|
190
|
+
*/
|
|
191
|
+
done(): DocumentBuilder;
|
|
192
|
+
/**
|
|
193
|
+
* Drop an uncommitted page. Use only for error recovery — the parent's
|
|
194
|
+
* open-page slot is released so the next `a4Page()` etc. succeeds.
|
|
195
|
+
*/
|
|
196
|
+
close(): void;
|
|
197
|
+
/** Symbol.dispose support for `using`. */
|
|
198
|
+
[Symbol.dispose](): void;
|
|
199
|
+
}
|
|
@@ -0,0 +1,434 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Fluent document builder — the programmatic multi-page construction API
|
|
3
|
+
* exposed through the C FFI.
|
|
4
|
+
*
|
|
5
|
+
* Mirrors the Python / WASM / C# / Go equivalents. The same handle-lifetime
|
|
6
|
+
* contract applies: terminal methods (`build`, `save`, `saveEncrypted`,
|
|
7
|
+
* `toBytesEncrypted`) CONSUME the builder, and only one `PageBuilder` may
|
|
8
|
+
* be open at a time.
|
|
9
|
+
*
|
|
10
|
+
* @example
|
|
11
|
+
* ```typescript
|
|
12
|
+
* import { DocumentBuilder, EmbeddedFont } from 'pdf-oxide';
|
|
13
|
+
*
|
|
14
|
+
* const font = EmbeddedFont.fromFile('DejaVuSans.ttf');
|
|
15
|
+
* const builder = DocumentBuilder.create()
|
|
16
|
+
* .title('Hello')
|
|
17
|
+
* .registerEmbeddedFont('DejaVu', font); // consumes `font`
|
|
18
|
+
* builder.a4Page()
|
|
19
|
+
* .font('DejaVu', 12)
|
|
20
|
+
* .at(72, 720).text('Привет, мир!')
|
|
21
|
+
* .at(72, 700).text('Καλημέρα κόσμε')
|
|
22
|
+
* .done();
|
|
23
|
+
* const bytes = builder.build(); // consumes the builder
|
|
24
|
+
* ```
|
|
25
|
+
*/
|
|
26
|
+
// Load the addon via the shared prebuild-aware loader — resolves
|
|
27
|
+
// against `prebuilds/<triple>/pdf_oxide.node` in the published
|
|
28
|
+
// package and the in-tree `build/Release/` output in dev mode.
|
|
29
|
+
import { loadNative } from '../native.js';
|
|
30
|
+
const native = loadNative();
|
|
31
|
+
/**
|
|
32
|
+
* TTF/OTF font handle registerable with {@link DocumentBuilder}. Single-use:
|
|
33
|
+
* after `registerEmbeddedFont` the native handle is moved into the builder
|
|
34
|
+
* and this object becomes disposed.
|
|
35
|
+
*/
|
|
36
|
+
export class EmbeddedFont {
|
|
37
|
+
constructor(handle) {
|
|
38
|
+
this._consumed = false;
|
|
39
|
+
this._handle = handle;
|
|
40
|
+
}
|
|
41
|
+
/** Load a TTF / OTF font from disk. */
|
|
42
|
+
static fromFile(path) {
|
|
43
|
+
return new EmbeddedFont(native.embeddedFontFromFile(path));
|
|
44
|
+
}
|
|
45
|
+
/** Load a font from a byte buffer; pass `name` to override the PostScript name. */
|
|
46
|
+
static fromBytes(data, name) {
|
|
47
|
+
return new EmbeddedFont(native.embeddedFontFromBytes(data, name));
|
|
48
|
+
}
|
|
49
|
+
/** @internal — used by {@link DocumentBuilder.registerEmbeddedFont} */
|
|
50
|
+
get handle() {
|
|
51
|
+
if (this._consumed) {
|
|
52
|
+
throw new Error('EmbeddedFont already consumed');
|
|
53
|
+
}
|
|
54
|
+
return this._handle;
|
|
55
|
+
}
|
|
56
|
+
/** @internal — called by the builder after the FFI transfers ownership. */
|
|
57
|
+
markConsumed() {
|
|
58
|
+
this._consumed = true;
|
|
59
|
+
this._handle = null;
|
|
60
|
+
}
|
|
61
|
+
/** Release the native font handle if it hasn't been consumed. */
|
|
62
|
+
close() {
|
|
63
|
+
if (!this._consumed && this._handle != null) {
|
|
64
|
+
native.embeddedFontFree(this._handle);
|
|
65
|
+
this._consumed = true;
|
|
66
|
+
this._handle = null;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
/** Symbol.dispose support for `using` declarations. */
|
|
70
|
+
[Symbol.dispose]() {
|
|
71
|
+
this.close();
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Fluent top-level API for multi-page PDF construction.
|
|
76
|
+
* Use {@link DocumentBuilder.create} to start a new builder.
|
|
77
|
+
*/
|
|
78
|
+
export class DocumentBuilder {
|
|
79
|
+
constructor(handle) {
|
|
80
|
+
this._consumed = false;
|
|
81
|
+
this._openPage = null;
|
|
82
|
+
this._handle = handle;
|
|
83
|
+
}
|
|
84
|
+
/** Create a fresh empty builder. */
|
|
85
|
+
static create() {
|
|
86
|
+
return new DocumentBuilder(native.documentBuilderCreate());
|
|
87
|
+
}
|
|
88
|
+
/** @internal — used by PageBuilder.done */
|
|
89
|
+
clearOpenPage() {
|
|
90
|
+
this._openPage = null;
|
|
91
|
+
}
|
|
92
|
+
checkUsable() {
|
|
93
|
+
if (this._consumed || this._handle == null) {
|
|
94
|
+
throw new Error('DocumentBuilder has been consumed');
|
|
95
|
+
}
|
|
96
|
+
if (this._openPage != null) {
|
|
97
|
+
throw new Error('A PageBuilder is already open; call done() first.');
|
|
98
|
+
}
|
|
99
|
+
return this._handle;
|
|
100
|
+
}
|
|
101
|
+
/** Set the document title. */
|
|
102
|
+
title(title) {
|
|
103
|
+
native.documentBuilderSetTitle(this.checkUsable(), title);
|
|
104
|
+
return this;
|
|
105
|
+
}
|
|
106
|
+
/** Set the document author. */
|
|
107
|
+
author(author) {
|
|
108
|
+
native.documentBuilderSetAuthor(this.checkUsable(), author);
|
|
109
|
+
return this;
|
|
110
|
+
}
|
|
111
|
+
/** Set the document subject. */
|
|
112
|
+
subject(subject) {
|
|
113
|
+
native.documentBuilderSetSubject(this.checkUsable(), subject);
|
|
114
|
+
return this;
|
|
115
|
+
}
|
|
116
|
+
/** Set the document keywords (comma-separated per PDF convention). */
|
|
117
|
+
keywords(keywords) {
|
|
118
|
+
native.documentBuilderSetKeywords(this.checkUsable(), keywords);
|
|
119
|
+
return this;
|
|
120
|
+
}
|
|
121
|
+
/** Set the creator application name. */
|
|
122
|
+
creator(creator) {
|
|
123
|
+
native.documentBuilderSetCreator(this.checkUsable(), creator);
|
|
124
|
+
return this;
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* Register a TTF / OTF font under `name`. CONSUMES `font` on success —
|
|
128
|
+
* do not call `close()` on the font afterwards.
|
|
129
|
+
*/
|
|
130
|
+
registerEmbeddedFont(name, font) {
|
|
131
|
+
const builderHandle = this.checkUsable();
|
|
132
|
+
// font.handle getter throws if already consumed, so validation is done.
|
|
133
|
+
native.documentBuilderRegisterEmbeddedFont(builderHandle, name, font.handle);
|
|
134
|
+
font.markConsumed();
|
|
135
|
+
return this;
|
|
136
|
+
}
|
|
137
|
+
/** Start a new A4 page. Only one page may be outstanding per builder. */
|
|
138
|
+
a4Page() {
|
|
139
|
+
const h = this.checkUsable();
|
|
140
|
+
const pageHandle = native.documentBuilderA4Page(h);
|
|
141
|
+
this._openPage = new PageBuilder(this, pageHandle);
|
|
142
|
+
return this._openPage;
|
|
143
|
+
}
|
|
144
|
+
/** Start a new US Letter page. */
|
|
145
|
+
letterPage() {
|
|
146
|
+
const h = this.checkUsable();
|
|
147
|
+
const pageHandle = native.documentBuilderLetterPage(h);
|
|
148
|
+
this._openPage = new PageBuilder(this, pageHandle);
|
|
149
|
+
return this._openPage;
|
|
150
|
+
}
|
|
151
|
+
/** Start a page with custom dimensions in PDF points (72 pt = 1 inch). */
|
|
152
|
+
page(width, height) {
|
|
153
|
+
const h = this.checkUsable();
|
|
154
|
+
const pageHandle = native.documentBuilderPage(h, width, height);
|
|
155
|
+
this._openPage = new PageBuilder(this, pageHandle);
|
|
156
|
+
return this._openPage;
|
|
157
|
+
}
|
|
158
|
+
consumeHandle() {
|
|
159
|
+
const h = this.checkUsable();
|
|
160
|
+
this._consumed = true;
|
|
161
|
+
this._handle = null;
|
|
162
|
+
return h;
|
|
163
|
+
}
|
|
164
|
+
/** Build the PDF and return the bytes. CONSUMES the builder. */
|
|
165
|
+
build() {
|
|
166
|
+
const h = this.consumeHandle();
|
|
167
|
+
try {
|
|
168
|
+
return native.documentBuilderBuild(h);
|
|
169
|
+
}
|
|
170
|
+
finally {
|
|
171
|
+
native.documentBuilderFree(h);
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
/** Save the PDF to a file. CONSUMES the builder. */
|
|
175
|
+
save(path) {
|
|
176
|
+
const h = this.consumeHandle();
|
|
177
|
+
try {
|
|
178
|
+
native.documentBuilderSave(h, path);
|
|
179
|
+
}
|
|
180
|
+
finally {
|
|
181
|
+
native.documentBuilderFree(h);
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
/** Save the PDF with AES-256 encryption. CONSUMES the builder. */
|
|
185
|
+
saveEncrypted(path, userPassword, ownerPassword) {
|
|
186
|
+
const h = this.consumeHandle();
|
|
187
|
+
try {
|
|
188
|
+
native.documentBuilderSaveEncrypted(h, path, userPassword, ownerPassword);
|
|
189
|
+
}
|
|
190
|
+
finally {
|
|
191
|
+
native.documentBuilderFree(h);
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
/** Return the PDF as encrypted bytes (AES-256). CONSUMES the builder. */
|
|
195
|
+
toBytesEncrypted(userPassword, ownerPassword) {
|
|
196
|
+
const h = this.consumeHandle();
|
|
197
|
+
try {
|
|
198
|
+
return native.documentBuilderToBytesEncrypted(h, userPassword, ownerPassword);
|
|
199
|
+
}
|
|
200
|
+
finally {
|
|
201
|
+
native.documentBuilderFree(h);
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
/** Release native resources if the builder wasn't consumed. */
|
|
205
|
+
close() {
|
|
206
|
+
if (!this._consumed && this._handle != null) {
|
|
207
|
+
native.documentBuilderFree(this._handle);
|
|
208
|
+
this._consumed = true;
|
|
209
|
+
this._handle = null;
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
/** Symbol.dispose support for `using` declarations. */
|
|
213
|
+
[Symbol.dispose]() {
|
|
214
|
+
this.close();
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
/**
|
|
218
|
+
* Fluent per-page builder returned by `DocumentBuilder.a4Page` etc.
|
|
219
|
+
* Single-use — `done()` commits the page and invalidates this builder.
|
|
220
|
+
*/
|
|
221
|
+
export class PageBuilder {
|
|
222
|
+
/** @internal — constructed by DocumentBuilder */
|
|
223
|
+
constructor(parent, handle) {
|
|
224
|
+
this._done = false;
|
|
225
|
+
this._parent = parent;
|
|
226
|
+
this._handle = handle;
|
|
227
|
+
}
|
|
228
|
+
h() {
|
|
229
|
+
if (this._done || this._handle == null) {
|
|
230
|
+
throw new Error('PageBuilder already committed');
|
|
231
|
+
}
|
|
232
|
+
return this._handle;
|
|
233
|
+
}
|
|
234
|
+
// --- content --------------------------------------------------------
|
|
235
|
+
/** Set font + size for subsequent text. */
|
|
236
|
+
font(name, size) {
|
|
237
|
+
native.pageBuilderFont(this.h(), name, size);
|
|
238
|
+
return this;
|
|
239
|
+
}
|
|
240
|
+
/** Move the cursor to absolute coordinates. */
|
|
241
|
+
at(x, y) {
|
|
242
|
+
native.pageBuilderAt(this.h(), x, y);
|
|
243
|
+
return this;
|
|
244
|
+
}
|
|
245
|
+
/** Emit a line of text at the current cursor position. */
|
|
246
|
+
text(text) {
|
|
247
|
+
native.pageBuilderText(this.h(), text);
|
|
248
|
+
return this;
|
|
249
|
+
}
|
|
250
|
+
/** Emit a heading (level 1-6). */
|
|
251
|
+
heading(level, text) {
|
|
252
|
+
native.pageBuilderHeading(this.h(), level, text);
|
|
253
|
+
return this;
|
|
254
|
+
}
|
|
255
|
+
/** Emit a paragraph with automatic line wrapping. */
|
|
256
|
+
paragraph(text) {
|
|
257
|
+
native.pageBuilderParagraph(this.h(), text);
|
|
258
|
+
return this;
|
|
259
|
+
}
|
|
260
|
+
/** Advance the cursor by the given number of points. */
|
|
261
|
+
space(points) {
|
|
262
|
+
native.pageBuilderSpace(this.h(), points);
|
|
263
|
+
return this;
|
|
264
|
+
}
|
|
265
|
+
/** Draw a horizontal rule across the page. */
|
|
266
|
+
horizontalRule() {
|
|
267
|
+
native.pageBuilderHorizontalRule(this.h());
|
|
268
|
+
return this;
|
|
269
|
+
}
|
|
270
|
+
// --- annotations (Phase 3) -----------------------------------------
|
|
271
|
+
/** Attach a URL link to the previous text element. */
|
|
272
|
+
linkUrl(url) {
|
|
273
|
+
native.pageBuilderLinkUrl(this.h(), url);
|
|
274
|
+
return this;
|
|
275
|
+
}
|
|
276
|
+
/** Link the previous text to an internal page (0-based). */
|
|
277
|
+
linkPage(pageIndex) {
|
|
278
|
+
native.pageBuilderLinkPage(this.h(), pageIndex);
|
|
279
|
+
return this;
|
|
280
|
+
}
|
|
281
|
+
/** Link the previous text to a named destination. */
|
|
282
|
+
linkNamed(destination) {
|
|
283
|
+
native.pageBuilderLinkNamed(this.h(), destination);
|
|
284
|
+
return this;
|
|
285
|
+
}
|
|
286
|
+
/** Highlight the previous text with an RGB colour (channels 0-1). */
|
|
287
|
+
highlight(r, g, b) {
|
|
288
|
+
native.pageBuilderHighlight(this.h(), r, g, b);
|
|
289
|
+
return this;
|
|
290
|
+
}
|
|
291
|
+
/** Underline the previous text. */
|
|
292
|
+
underline(r, g, b) {
|
|
293
|
+
native.pageBuilderUnderline(this.h(), r, g, b);
|
|
294
|
+
return this;
|
|
295
|
+
}
|
|
296
|
+
/** Strike through the previous text. */
|
|
297
|
+
strikeout(r, g, b) {
|
|
298
|
+
native.pageBuilderStrikeout(this.h(), r, g, b);
|
|
299
|
+
return this;
|
|
300
|
+
}
|
|
301
|
+
/** Squiggly-underline the previous text. */
|
|
302
|
+
squiggly(r, g, b) {
|
|
303
|
+
native.pageBuilderSquiggly(this.h(), r, g, b);
|
|
304
|
+
return this;
|
|
305
|
+
}
|
|
306
|
+
/** Attach a sticky-note annotation to the previous text. */
|
|
307
|
+
stickyNote(text) {
|
|
308
|
+
native.pageBuilderStickyNote(this.h(), text);
|
|
309
|
+
return this;
|
|
310
|
+
}
|
|
311
|
+
/** Place a sticky-note at an absolute position. */
|
|
312
|
+
stickyNoteAt(x, y, text) {
|
|
313
|
+
native.pageBuilderStickyNoteAt(this.h(), x, y, text);
|
|
314
|
+
return this;
|
|
315
|
+
}
|
|
316
|
+
/** Apply a text watermark to the page. */
|
|
317
|
+
watermark(text) {
|
|
318
|
+
native.pageBuilderWatermark(this.h(), text);
|
|
319
|
+
return this;
|
|
320
|
+
}
|
|
321
|
+
/** Apply the standard "CONFIDENTIAL" diagonal watermark. */
|
|
322
|
+
watermarkConfidential() {
|
|
323
|
+
native.pageBuilderWatermarkConfidential(this.h());
|
|
324
|
+
return this;
|
|
325
|
+
}
|
|
326
|
+
/** Apply the standard "DRAFT" diagonal watermark. */
|
|
327
|
+
watermarkDraft() {
|
|
328
|
+
native.pageBuilderWatermarkDraft(this.h());
|
|
329
|
+
return this;
|
|
330
|
+
}
|
|
331
|
+
/**
|
|
332
|
+
* Attach a standard stamp annotation at the cursor (150×50 default).
|
|
333
|
+
* `typeName` matches the PDF spec's standard stamps (Approved,
|
|
334
|
+
* NotApproved, Draft, Confidential, Final, Experimental, Expired,
|
|
335
|
+
* ForPublicRelease, NotForPublicRelease, AsIs, Sold, Departmental,
|
|
336
|
+
* ForComment, TopSecret) — any other name becomes a custom stamp.
|
|
337
|
+
*/
|
|
338
|
+
stamp(typeName) {
|
|
339
|
+
native.pageBuilderStamp(this.h(), typeName);
|
|
340
|
+
return this;
|
|
341
|
+
}
|
|
342
|
+
/** Place a free-flowing text annotation inside the rectangle (x, y, w, h). */
|
|
343
|
+
freeText(x, y, w, h, text) {
|
|
344
|
+
native.pageBuilderFreetext(this.h(), x, y, w, h, text);
|
|
345
|
+
return this;
|
|
346
|
+
}
|
|
347
|
+
// --- Form-field widgets --------------------------------------------
|
|
348
|
+
/**
|
|
349
|
+
* Add a single-line text form field at the rectangle (x, y, w, h).
|
|
350
|
+
* `name` is the unique field identifier used for form submission;
|
|
351
|
+
* `defaultValue` is the initial text (pass undefined for blank).
|
|
352
|
+
*/
|
|
353
|
+
textField(name, x, y, w, h, defaultValue) {
|
|
354
|
+
native.pageBuilderTextField(this.h(), name, x, y, w, h, defaultValue);
|
|
355
|
+
return this;
|
|
356
|
+
}
|
|
357
|
+
/**
|
|
358
|
+
* Add a checkbox form field at the rectangle (x, y, w, h).
|
|
359
|
+
* `checked` sets the initial state.
|
|
360
|
+
*/
|
|
361
|
+
checkbox(name, x, y, w, h, checked = false) {
|
|
362
|
+
native.pageBuilderCheckbox(this.h(), name, x, y, w, h, checked);
|
|
363
|
+
return this;
|
|
364
|
+
}
|
|
365
|
+
/**
|
|
366
|
+
* Add a dropdown combo-box form field. `options` are the user-
|
|
367
|
+
* visible choices; `selected` picks the initial value.
|
|
368
|
+
*/
|
|
369
|
+
comboBox(name, x, y, w, h, options, selected) {
|
|
370
|
+
native.pageBuilderComboBox(this.h(), name, x, y, w, h, options, selected);
|
|
371
|
+
return this;
|
|
372
|
+
}
|
|
373
|
+
/**
|
|
374
|
+
* Add a radio-button group. `buttons` is an array of
|
|
375
|
+
* `[exportValue, x, y, w, h]` tuples — one per option. `selected`
|
|
376
|
+
* picks the initial value by export value.
|
|
377
|
+
*/
|
|
378
|
+
radioGroup(name, buttons, selected) {
|
|
379
|
+
native.pageBuilderRadioGroup(this.h(), name, buttons, selected);
|
|
380
|
+
return this;
|
|
381
|
+
}
|
|
382
|
+
/** Add a clickable push button with a visible caption. */
|
|
383
|
+
pushButton(name, x, y, w, h, caption) {
|
|
384
|
+
native.pageBuilderPushButton(this.h(), name, x, y, w, h, caption);
|
|
385
|
+
return this;
|
|
386
|
+
}
|
|
387
|
+
// --- Low-level graphics primitives ---------------------------------
|
|
388
|
+
/** Draw a stroked rectangle outline (1pt black). */
|
|
389
|
+
rect(x, y, w, h) {
|
|
390
|
+
native.pageBuilderRect(this.h(), x, y, w, h);
|
|
391
|
+
return this;
|
|
392
|
+
}
|
|
393
|
+
/** Draw a filled rectangle in RGB colour (channels 0–1). */
|
|
394
|
+
filledRect(x, y, w, h, r, g, b) {
|
|
395
|
+
native.pageBuilderFilledRect(this.h(), x, y, w, h, r, g, b);
|
|
396
|
+
return this;
|
|
397
|
+
}
|
|
398
|
+
/** Draw a line from `(x1, y1)` to `(x2, y2)` with 1pt black stroke. */
|
|
399
|
+
line(x1, y1, x2, y2) {
|
|
400
|
+
native.pageBuilderLine(this.h(), x1, y1, x2, y2);
|
|
401
|
+
return this;
|
|
402
|
+
}
|
|
403
|
+
/**
|
|
404
|
+
* Commit the page's buffered operations to the parent builder and
|
|
405
|
+
* return the parent for chaining. After `done()` this PageBuilder is
|
|
406
|
+
* invalid.
|
|
407
|
+
*/
|
|
408
|
+
done() {
|
|
409
|
+
if (this._done) {
|
|
410
|
+
throw new Error('PageBuilder already committed');
|
|
411
|
+
}
|
|
412
|
+
native.pageBuilderDone(this._handle);
|
|
413
|
+
this._done = true;
|
|
414
|
+
this._handle = null;
|
|
415
|
+
this._parent.clearOpenPage();
|
|
416
|
+
return this._parent;
|
|
417
|
+
}
|
|
418
|
+
/**
|
|
419
|
+
* Drop an uncommitted page. Use only for error recovery — the parent's
|
|
420
|
+
* open-page slot is released so the next `a4Page()` etc. succeeds.
|
|
421
|
+
*/
|
|
422
|
+
close() {
|
|
423
|
+
if (!this._done && this._handle != null) {
|
|
424
|
+
native.pageBuilderFree(this._handle);
|
|
425
|
+
this._parent.clearOpenPage();
|
|
426
|
+
this._done = true;
|
|
427
|
+
this._handle = null;
|
|
428
|
+
}
|
|
429
|
+
}
|
|
430
|
+
/** Symbol.dispose support for `using`. */
|
|
431
|
+
[Symbol.dispose]() {
|
|
432
|
+
this.close();
|
|
433
|
+
}
|
|
434
|
+
}
|
package/lib/builders/index.d.ts
CHANGED
|
@@ -4,8 +4,9 @@
|
|
|
4
4
|
* This module exports builder classes that implement the fluent builder pattern
|
|
5
5
|
* for configuring PDF documents, annotations, search options, metadata, and conversion.
|
|
6
6
|
*/
|
|
7
|
-
export * from './
|
|
7
|
+
export * from './annotation-builder';
|
|
8
8
|
export * from './conversion-options-builder';
|
|
9
|
+
export * from './document-builder';
|
|
9
10
|
export * from './metadata-builder';
|
|
10
|
-
export * from './
|
|
11
|
+
export * from './pdf-builder';
|
|
11
12
|
export * from './search-options-builder';
|
package/lib/builders/index.js
CHANGED
|
@@ -4,8 +4,9 @@
|
|
|
4
4
|
* This module exports builder classes that implement the fluent builder pattern
|
|
5
5
|
* for configuring PDF documents, annotations, search options, metadata, and conversion.
|
|
6
6
|
*/
|
|
7
|
-
export * from './
|
|
7
|
+
export * from './annotation-builder.js';
|
|
8
8
|
export * from './conversion-options-builder.js';
|
|
9
|
+
export * from './document-builder.js';
|
|
9
10
|
export * from './metadata-builder.js';
|
|
10
|
-
export * from './
|
|
11
|
+
export * from './pdf-builder.js';
|
|
11
12
|
export * from './search-options-builder.js';
|