pdf-lite 1.4.0 → 1.5.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/dist/acroform/acroform.d.ts +3 -3
- package/dist/acroform/acroform.js +2 -2
- package/dist/acroform/appearance/index.d.ts +4 -4
- package/dist/acroform/appearance/index.js +4 -4
- package/dist/acroform/appearance/{PdfAppearanceStream.d.ts → pdf-appearance-stream.d.ts} +9 -3
- package/dist/acroform/appearance/{PdfAppearanceStream.js → pdf-appearance-stream.js} +14 -5
- package/dist/acroform/appearance/{PdfButtonAppearanceStream.d.ts → pdf-button-appearance-stream.d.ts} +3 -2
- package/dist/acroform/appearance/pdf-button-appearance-stream.js +54 -0
- package/dist/acroform/appearance/pdf-choice-appearance-stream.d.ts +22 -0
- package/dist/acroform/appearance/pdf-choice-appearance-stream.js +75 -0
- package/dist/acroform/appearance/pdf-graphics.d.ts +51 -0
- package/dist/acroform/appearance/pdf-graphics.js +239 -0
- package/dist/acroform/appearance/{PdfTextAppearanceStream.d.ts → pdf-text-appearance-stream.d.ts} +7 -2
- package/dist/acroform/appearance/pdf-text-appearance-stream.js +104 -0
- package/dist/acroform/fields/index.d.ts +7 -7
- package/dist/acroform/fields/index.js +7 -7
- package/dist/acroform/fields/pdf-button-form-field.d.ts +23 -0
- package/dist/acroform/fields/pdf-button-form-field.js +102 -0
- package/dist/acroform/fields/pdf-choice-form-field.d.ts +18 -0
- package/dist/acroform/fields/pdf-choice-form-field.js +131 -0
- package/dist/acroform/fields/{PdfFormFieldFlags.d.ts → pdf-form-field-flags.d.ts} +5 -6
- package/dist/acroform/fields/{PdfFormFieldFlags.js → pdf-form-field-flags.js} +12 -18
- package/dist/acroform/fields/{PdfFormField.d.ts → pdf-form-field.d.ts} +15 -11
- package/dist/acroform/fields/{PdfFormField.js → pdf-form-field.js} +68 -134
- package/dist/acroform/fields/{PdfSignatureFormField.d.ts → pdf-signature-form-field.d.ts} +1 -1
- package/dist/acroform/fields/{PdfSignatureFormField.js → pdf-signature-form-field.js} +1 -1
- package/dist/acroform/fields/{PdfTextFormField.d.ts → pdf-text-form-field.d.ts} +1 -1
- package/dist/acroform/fields/pdf-text-form-field.js +77 -0
- package/dist/acroform/fields/types.d.ts +5 -0
- package/dist/acroform/index.d.ts +2 -2
- package/dist/acroform/index.js +2 -2
- package/dist/acroform/manager.d.ts +7 -3
- package/dist/acroform/manager.js +14 -8
- package/dist/acroform/{PdfAcroForm.d.ts → pdf-acro-form.d.ts} +12 -6
- package/dist/acroform/{PdfAcroForm.js → pdf-acro-form.js} +43 -29
- package/dist/acroform/{PdfFontEncodingCache.d.ts → pdf-font-encoding-cache.d.ts} +11 -0
- package/dist/acroform/pdf-font-encoding-cache.js +188 -0
- package/dist/acroform/xfa/index.d.ts +3 -3
- package/dist/acroform/xfa/index.js +2 -2
- package/dist/acroform/xfa/{PdfXfaForm.d.ts → pdf-xfa-form.d.ts} +1 -2
- package/dist/acroform/xfa/{PdfXfaForm.js → pdf-xfa-form.js} +2 -10
- package/dist/annotations/index.d.ts +4 -4
- package/dist/annotations/index.js +4 -4
- package/dist/annotations/{PdfAnnotationFlags.d.ts → pdf-annotation-flags.d.ts} +3 -4
- package/dist/annotations/{PdfAnnotationFlags.js → pdf-annotation-flags.js} +5 -6
- package/dist/annotations/{PdfAnnotation.d.ts → pdf-annotation.d.ts} +25 -4
- package/dist/annotations/{PdfAnnotation.js → pdf-annotation.js} +4 -3
- package/dist/annotations/{PdfWidgetAnnotation.d.ts → pdf-widget-annotation.d.ts} +1 -1
- package/dist/annotations/{PdfWidgetAnnotation.js → pdf-widget-annotation.js} +1 -1
- package/dist/core/objects/pdf-stream.d.ts +1 -0
- package/dist/core/objects/pdf-stream.js +6 -2
- package/dist/core/parser/incremental-parser.d.ts +0 -13
- package/dist/core/parser/incremental-parser.js +1 -18
- package/dist/core/streams/object-stream.d.ts +1 -1
- package/dist/core/streams/object-stream.js +1 -1
- package/dist/errors.d.ts +22 -0
- package/dist/errors.js +24 -0
- package/dist/fonts/index.d.ts +1 -1
- package/dist/fonts/index.js +1 -1
- package/dist/fonts/pdf-font.d.ts +64 -7
- package/dist/fonts/pdf-font.js +188 -8
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/pdf/index.d.ts +0 -1
- package/dist/pdf/index.js +0 -1
- package/dist/pdf/pdf-document.d.ts +2 -1
- package/dist/pdf/pdf-document.js +15 -11
- package/dist/utils/encodePdfText.d.ts +17 -0
- package/dist/utils/encodePdfText.js +61 -0
- package/dist/utils/index.d.ts +1 -1
- package/dist/utils/index.js +1 -1
- package/package.json +1 -1
- package/dist/acroform/PdfFontEncodingCache.js +0 -75
- package/dist/acroform/appearance/PdfButtonAppearanceStream.js +0 -54
- package/dist/acroform/appearance/PdfChoiceAppearanceStream.d.ts +0 -15
- package/dist/acroform/appearance/PdfChoiceAppearanceStream.js +0 -48
- package/dist/acroform/appearance/PdfTextAppearanceStream.js +0 -75
- package/dist/acroform/fields/PdfButtonFormField.d.ts +0 -9
- package/dist/acroform/fields/PdfButtonFormField.js +0 -35
- package/dist/acroform/fields/PdfChoiceFormField.d.ts +0 -9
- package/dist/acroform/fields/PdfChoiceFormField.js +0 -46
- package/dist/acroform/fields/PdfTextFormField.js +0 -52
- package/dist/pdf/errors.d.ts +0 -6
- package/dist/pdf/errors.js +0 -6
- /package/dist/acroform/fields/{PdfDefaultAppearance.d.ts → pdf-default-appearance.d.ts} +0 -0
- /package/dist/acroform/fields/{PdfDefaultAppearance.js → pdf-default-appearance.js} +0 -0
- /package/dist/acroform/xfa/{PdfXfaData.d.ts → pdf-xfa-data.d.ts} +0 -0
- /package/dist/acroform/xfa/{PdfXfaData.js → pdf-xfa-data.js} +0 -0
- /package/dist/annotations/{PdfAnnotationWriter.d.ts → pdf-annotation-writer.d.ts} +0 -0
- /package/dist/annotations/{PdfAnnotationWriter.js → pdf-annotation-writer.js} +0 -0
- /package/dist/fonts/{font-manager.d.ts → manager.d.ts} +0 -0
- /package/dist/fonts/{font-manager.js → manager.js} +0 -0
- /package/dist/utils/{IterableReadableStream.d.ts → iterable-readable-stream.d.ts} +0 -0
- /package/dist/utils/{IterableReadableStream.js → iterable-readable-stream.js} +0 -0
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
import { PdfDefaultAppearance } from '../fields/pdf-default-appearance.js';
|
|
2
|
+
import { PdfAppearanceStream } from './pdf-appearance-stream.js';
|
|
3
|
+
import { PdfGraphics } from './pdf-graphics.js';
|
|
4
|
+
/**
|
|
5
|
+
* Appearance stream for text fields (single-line, multiline, comb).
|
|
6
|
+
* Enhanced with word wrapping and automatic font scaling.
|
|
7
|
+
*/
|
|
8
|
+
export class PdfTextAppearanceStream extends PdfAppearanceStream {
|
|
9
|
+
constructor(ctx) {
|
|
10
|
+
const [x1, y1, x2, y2] = ctx.rect;
|
|
11
|
+
const width = x2 - x1;
|
|
12
|
+
const height = y2 - y1;
|
|
13
|
+
const value = ctx.value;
|
|
14
|
+
const isUnicode = ctx.isUnicode ?? false;
|
|
15
|
+
const reverseEncodingMap = ctx.reverseEncodingMap;
|
|
16
|
+
const padding = 2;
|
|
17
|
+
const availableWidth = width - 2 * padding;
|
|
18
|
+
const availableHeight = height - 2 * padding;
|
|
19
|
+
// Create graphics with font context for text measurement
|
|
20
|
+
const g = new PdfGraphics({
|
|
21
|
+
resolvedFonts: ctx.resolvedFonts,
|
|
22
|
+
});
|
|
23
|
+
g.beginMarkedContent();
|
|
24
|
+
g.save();
|
|
25
|
+
// Set initial font to enable measurement
|
|
26
|
+
g.setDefaultAppearance(ctx.da);
|
|
27
|
+
let finalFontSize = ctx.da.fontSize;
|
|
28
|
+
let lines = [];
|
|
29
|
+
if (ctx.multiline) {
|
|
30
|
+
const testLines = g.wrapTextToLines(value, availableWidth);
|
|
31
|
+
const lineHeight = finalFontSize * 1.2;
|
|
32
|
+
if (testLines.length * lineHeight > availableHeight) {
|
|
33
|
+
// Scale font down to fit
|
|
34
|
+
finalFontSize = g.calculateFittingFontSize(value, availableWidth, availableHeight, 1.2);
|
|
35
|
+
const adjustedDA = new PdfDefaultAppearance(ctx.da.fontName, finalFontSize, ctx.da.colorOp);
|
|
36
|
+
g.setDefaultAppearance(adjustedDA);
|
|
37
|
+
lines = g.wrapTextToLines(value, availableWidth);
|
|
38
|
+
}
|
|
39
|
+
else {
|
|
40
|
+
lines = testLines;
|
|
41
|
+
}
|
|
42
|
+
const renderLineHeight = finalFontSize * 1.2;
|
|
43
|
+
const startY = height - padding - finalFontSize;
|
|
44
|
+
g.beginText();
|
|
45
|
+
g.moveTo(padding, startY);
|
|
46
|
+
for (let i = 0; i < lines.length; i++) {
|
|
47
|
+
if (i > 0)
|
|
48
|
+
g.moveTo(0, -renderLineHeight);
|
|
49
|
+
g.showText(lines[i].replace(/\r/g, ''), isUnicode, reverseEncodingMap);
|
|
50
|
+
}
|
|
51
|
+
g.endText();
|
|
52
|
+
}
|
|
53
|
+
else if (ctx.comb && ctx.maxLen) {
|
|
54
|
+
const cellWidth = width / ctx.maxLen;
|
|
55
|
+
const chars = [...value];
|
|
56
|
+
// Calculate font size to fit the widest character in its cell
|
|
57
|
+
let maxCharWidth = 0;
|
|
58
|
+
let widestChar = chars[0] ?? '';
|
|
59
|
+
for (const char of chars) {
|
|
60
|
+
const charWidth = g.measureTextWidth(char);
|
|
61
|
+
if (charWidth > maxCharWidth) {
|
|
62
|
+
maxCharWidth = charWidth;
|
|
63
|
+
widestChar = char;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
if (maxCharWidth > cellWidth) {
|
|
67
|
+
finalFontSize = g.calculateFittingFontSize(widestChar, cellWidth);
|
|
68
|
+
const adjustedDA = new PdfDefaultAppearance(ctx.da.fontName, finalFontSize, ctx.da.colorOp);
|
|
69
|
+
g.setDefaultAppearance(adjustedDA);
|
|
70
|
+
}
|
|
71
|
+
const textY = (height - finalFontSize) / 2 + finalFontSize * 0.2;
|
|
72
|
+
g.beginText();
|
|
73
|
+
for (let i = 0; i < chars.length && i < ctx.maxLen; i++) {
|
|
74
|
+
const cellX = cellWidth * i + cellWidth / 2 - finalFontSize * 0.3;
|
|
75
|
+
g.moveTo(cellX, textY);
|
|
76
|
+
g.showText(chars[i], isUnicode, reverseEncodingMap);
|
|
77
|
+
g.moveTo(-cellX, -textY);
|
|
78
|
+
}
|
|
79
|
+
g.endText();
|
|
80
|
+
}
|
|
81
|
+
else {
|
|
82
|
+
// Single line text
|
|
83
|
+
const textWidth = g.measureTextWidth(value);
|
|
84
|
+
if (textWidth > availableWidth) {
|
|
85
|
+
finalFontSize = g.calculateFittingFontSize(value, availableWidth);
|
|
86
|
+
const adjustedDA = new PdfDefaultAppearance(ctx.da.fontName, finalFontSize, ctx.da.colorOp);
|
|
87
|
+
g.setDefaultAppearance(adjustedDA);
|
|
88
|
+
}
|
|
89
|
+
const textY = (height - finalFontSize) / 2 + finalFontSize * 0.2;
|
|
90
|
+
g.beginText();
|
|
91
|
+
g.moveTo(padding, textY);
|
|
92
|
+
g.showText(value, isUnicode, reverseEncodingMap);
|
|
93
|
+
g.endText();
|
|
94
|
+
}
|
|
95
|
+
g.restore();
|
|
96
|
+
g.endMarkedContent();
|
|
97
|
+
super({
|
|
98
|
+
width,
|
|
99
|
+
height,
|
|
100
|
+
contentStream: g.build(),
|
|
101
|
+
resources: ctx.fontResources,
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
export { PdfFormField, PdfAcroFormField } from './
|
|
2
|
-
export { PdfFormFieldFlags } from './
|
|
3
|
-
export { PdfDefaultAppearance } from './
|
|
4
|
-
export { PdfTextFormField } from './
|
|
5
|
-
export { PdfButtonFormField } from './
|
|
6
|
-
export { PdfChoiceFormField } from './
|
|
7
|
-
export { PdfSignatureFormField } from './
|
|
1
|
+
export { PdfFormField, PdfAcroFormField } from './pdf-form-field.js';
|
|
2
|
+
export { PdfFormFieldFlags } from './pdf-form-field-flags.js';
|
|
3
|
+
export { PdfDefaultAppearance } from './pdf-default-appearance.js';
|
|
4
|
+
export { PdfTextFormField } from './pdf-text-form-field.js';
|
|
5
|
+
export { PdfButtonFormField } from './pdf-button-form-field.js';
|
|
6
|
+
export { PdfChoiceFormField } from './pdf-choice-form-field.js';
|
|
7
|
+
export { PdfSignatureFormField } from './pdf-signature-form-field.js';
|
|
8
8
|
export { PdfFieldType, type FormContext } from './types.js';
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
export { PdfFormField, PdfAcroFormField } from './
|
|
2
|
-
export { PdfFormFieldFlags } from './
|
|
3
|
-
export { PdfDefaultAppearance } from './
|
|
4
|
-
export { PdfTextFormField } from './
|
|
5
|
-
export { PdfButtonFormField } from './
|
|
6
|
-
export { PdfChoiceFormField } from './
|
|
7
|
-
export { PdfSignatureFormField } from './
|
|
1
|
+
export { PdfFormField, PdfAcroFormField } from './pdf-form-field.js';
|
|
2
|
+
export { PdfFormFieldFlags } from './pdf-form-field-flags.js';
|
|
3
|
+
export { PdfDefaultAppearance } from './pdf-default-appearance.js';
|
|
4
|
+
export { PdfTextFormField } from './pdf-text-form-field.js';
|
|
5
|
+
export { PdfButtonFormField } from './pdf-button-form-field.js';
|
|
6
|
+
export { PdfChoiceFormField } from './pdf-choice-form-field.js';
|
|
7
|
+
export { PdfSignatureFormField } from './pdf-signature-form-field.js';
|
|
8
8
|
export { PdfFieldType } from './types.js';
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { PdfFormField } from './pdf-form-field.js';
|
|
2
|
+
import { PdfString } from '../../core/objects/pdf-string.js';
|
|
3
|
+
import { PdfObjectReference } from '../../core/objects/pdf-object-reference.js';
|
|
4
|
+
import type { PdfAppearanceStream } from '../appearance/pdf-appearance-stream.js';
|
|
5
|
+
import type { PdfStream } from '../../core/objects/pdf-stream.js';
|
|
6
|
+
/**
|
|
7
|
+
* Button form field subtype (checkboxes, radio buttons, push buttons).
|
|
8
|
+
*/
|
|
9
|
+
export declare class PdfButtonFormField extends PdfFormField {
|
|
10
|
+
set defaultValue(val: string);
|
|
11
|
+
protected _storeValue(val: string | PdfString, fieldParent: PdfFormField | undefined): boolean;
|
|
12
|
+
get checked(): boolean;
|
|
13
|
+
set checked(isChecked: boolean);
|
|
14
|
+
getAppearanceStream(): PdfStream | undefined;
|
|
15
|
+
getAppearanceStreamsForWriting(): {
|
|
16
|
+
primary: PdfAppearanceStream;
|
|
17
|
+
secondary?: PdfAppearanceStream;
|
|
18
|
+
} | undefined;
|
|
19
|
+
setAppearanceReference(appearanceStreamRef: PdfObjectReference, appearanceStreamYesRef?: PdfObjectReference): void;
|
|
20
|
+
generateAppearance(options?: {
|
|
21
|
+
makeReadOnly?: boolean;
|
|
22
|
+
}): boolean;
|
|
23
|
+
}
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
import { PdfFormField } from './pdf-form-field.js';
|
|
2
|
+
import { PdfButtonAppearanceStream } from '../appearance/pdf-button-appearance-stream.js';
|
|
3
|
+
import { PdfName } from '../../core/objects/pdf-name.js';
|
|
4
|
+
import { PdfString } from '../../core/objects/pdf-string.js';
|
|
5
|
+
import { PdfDictionary } from '../../core/objects/pdf-dictionary.js';
|
|
6
|
+
/**
|
|
7
|
+
* Button form field subtype (checkboxes, radio buttons, push buttons).
|
|
8
|
+
*/
|
|
9
|
+
export class PdfButtonFormField extends PdfFormField {
|
|
10
|
+
static {
|
|
11
|
+
PdfFormField.registerFieldType('Btn', PdfButtonFormField);
|
|
12
|
+
}
|
|
13
|
+
set defaultValue(val) {
|
|
14
|
+
this.content.set('DV', new PdfName(val));
|
|
15
|
+
}
|
|
16
|
+
_storeValue(val, fieldParent) {
|
|
17
|
+
const strVal = val instanceof PdfString ? val.value : val;
|
|
18
|
+
if (strVal.trim() === '') {
|
|
19
|
+
this.content.delete('V');
|
|
20
|
+
fieldParent?.content.delete('V');
|
|
21
|
+
this.content.delete('AS');
|
|
22
|
+
return false;
|
|
23
|
+
}
|
|
24
|
+
this.content.set('V', new PdfName(strVal));
|
|
25
|
+
fieldParent?.content.set('V', new PdfName(strVal));
|
|
26
|
+
this.content.set('AS', new PdfName(strVal));
|
|
27
|
+
return true;
|
|
28
|
+
}
|
|
29
|
+
get checked() {
|
|
30
|
+
const v = this.content.get('V') ?? this.parent?.content.get('V');
|
|
31
|
+
return v instanceof PdfName && v.value === 'Yes';
|
|
32
|
+
}
|
|
33
|
+
set checked(isChecked) {
|
|
34
|
+
const target = this.parent ?? this;
|
|
35
|
+
if (isChecked) {
|
|
36
|
+
target.content.set('V', new PdfName('Yes'));
|
|
37
|
+
this.content.set('AS', new PdfName('Yes'));
|
|
38
|
+
}
|
|
39
|
+
else {
|
|
40
|
+
target.content.set('V', new PdfName('Off'));
|
|
41
|
+
this.content.set('AS', new PdfName('Off'));
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
getAppearanceStream() {
|
|
45
|
+
if (this.checked && this._appearanceStreamYes) {
|
|
46
|
+
return this._appearanceStreamYes.content;
|
|
47
|
+
}
|
|
48
|
+
return this._appearanceStream?.content;
|
|
49
|
+
}
|
|
50
|
+
getAppearanceStreamsForWriting() {
|
|
51
|
+
if (!this._appearanceStream)
|
|
52
|
+
return undefined;
|
|
53
|
+
return {
|
|
54
|
+
primary: this._appearanceStream,
|
|
55
|
+
secondary: this._appearanceStreamYes,
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
setAppearanceReference(appearanceStreamRef, appearanceStreamYesRef) {
|
|
59
|
+
let apDict = this.appearanceStreamDict;
|
|
60
|
+
if (!apDict) {
|
|
61
|
+
apDict = new PdfDictionary();
|
|
62
|
+
this.appearanceStreamDict = apDict;
|
|
63
|
+
}
|
|
64
|
+
if (appearanceStreamYesRef) {
|
|
65
|
+
const stateDict = new PdfDictionary();
|
|
66
|
+
stateDict.set('Off', appearanceStreamRef);
|
|
67
|
+
stateDict.set('Yes', appearanceStreamYesRef);
|
|
68
|
+
apDict.set('N', stateDict);
|
|
69
|
+
}
|
|
70
|
+
else {
|
|
71
|
+
apDict.set('N', appearanceStreamRef);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
generateAppearance(options) {
|
|
75
|
+
const rect = this.rect;
|
|
76
|
+
if (!rect || rect.length !== 4)
|
|
77
|
+
return false;
|
|
78
|
+
const [x1, y1, x2, y2] = rect;
|
|
79
|
+
const width = x2 - x1;
|
|
80
|
+
const height = y2 - y1;
|
|
81
|
+
this._appearanceStream = new PdfButtonAppearanceStream({
|
|
82
|
+
width,
|
|
83
|
+
height,
|
|
84
|
+
contentStream: '',
|
|
85
|
+
});
|
|
86
|
+
// Merge own flags with parent flags so inherited bits (e.g. Radio) are
|
|
87
|
+
// not lost when a child widget has its own Ff entry (even Ff: 0).
|
|
88
|
+
const effectiveFlags = this.flags.flags | (this.parent?.flags?.flags ?? 0);
|
|
89
|
+
const yesContent = PdfButtonAppearanceStream.buildYesContent(width, height, effectiveFlags);
|
|
90
|
+
this._appearanceStreamYes = new PdfButtonAppearanceStream({
|
|
91
|
+
width,
|
|
92
|
+
height,
|
|
93
|
+
contentStream: yesContent,
|
|
94
|
+
});
|
|
95
|
+
if (options?.makeReadOnly) {
|
|
96
|
+
this.readOnly = true;
|
|
97
|
+
this.print = true;
|
|
98
|
+
this.noZoom = true;
|
|
99
|
+
}
|
|
100
|
+
return true;
|
|
101
|
+
}
|
|
102
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { PdfFormField } from './pdf-form-field.js';
|
|
2
|
+
/**
|
|
3
|
+
* Choice form field subtype (dropdowns, list boxes).
|
|
4
|
+
*/
|
|
5
|
+
export declare class PdfChoiceFormField extends PdfFormField {
|
|
6
|
+
get selectedIndex(): number;
|
|
7
|
+
get options(): {
|
|
8
|
+
label: string;
|
|
9
|
+
value: string;
|
|
10
|
+
}[];
|
|
11
|
+
set options(values: {
|
|
12
|
+
label: string;
|
|
13
|
+
value: string;
|
|
14
|
+
}[] | string[] | undefined);
|
|
15
|
+
generateAppearance(options?: {
|
|
16
|
+
makeReadOnly?: boolean;
|
|
17
|
+
}): boolean;
|
|
18
|
+
}
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
import { PdfFormField } from './pdf-form-field.js';
|
|
2
|
+
import { PdfDefaultAppearance } from './pdf-default-appearance.js';
|
|
3
|
+
import { PdfChoiceAppearanceStream } from '../appearance/pdf-choice-appearance-stream.js';
|
|
4
|
+
import { PdfDictionary } from '../../core/objects/pdf-dictionary.js';
|
|
5
|
+
import { PdfObjectReference } from '../../core/objects/pdf-object-reference.js';
|
|
6
|
+
import { PdfArray } from '../../core/objects/pdf-array.js';
|
|
7
|
+
import { PdfString } from '../../core/objects/pdf-string.js';
|
|
8
|
+
/**
|
|
9
|
+
* Choice form field subtype (dropdowns, list boxes).
|
|
10
|
+
*/
|
|
11
|
+
export class PdfChoiceFormField extends PdfFormField {
|
|
12
|
+
static {
|
|
13
|
+
PdfFormField.registerFieldType('Ch', PdfChoiceFormField);
|
|
14
|
+
}
|
|
15
|
+
get selectedIndex() {
|
|
16
|
+
return this.options.findIndex((opt) => opt.value === this.value);
|
|
17
|
+
}
|
|
18
|
+
get options() {
|
|
19
|
+
const opt = this.content
|
|
20
|
+
.get('Opt')
|
|
21
|
+
?.as((PdfArray)) ??
|
|
22
|
+
this.parent?.content
|
|
23
|
+
.get('Opt')
|
|
24
|
+
?.as((PdfArray));
|
|
25
|
+
if (!opt)
|
|
26
|
+
return [];
|
|
27
|
+
return opt.items.map((item) => {
|
|
28
|
+
if (item instanceof PdfArray && item.items.length >= 2) {
|
|
29
|
+
const label = item.items[1] instanceof PdfString
|
|
30
|
+
? item.items[1].value
|
|
31
|
+
: '';
|
|
32
|
+
const value = item.items[0] instanceof PdfString
|
|
33
|
+
? item.items[0].value
|
|
34
|
+
: '';
|
|
35
|
+
return { label, value };
|
|
36
|
+
}
|
|
37
|
+
else if (item instanceof PdfString) {
|
|
38
|
+
return { label: item.value, value: item.value };
|
|
39
|
+
}
|
|
40
|
+
else {
|
|
41
|
+
return { label: '', value: '' };
|
|
42
|
+
}
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
set options(values) {
|
|
46
|
+
if (values === undefined) {
|
|
47
|
+
this.content.delete('Opt');
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
if (values.length === 0) {
|
|
51
|
+
this.content.delete('Opt');
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
const optArray = new PdfArray();
|
|
55
|
+
for (const option of values) {
|
|
56
|
+
if (typeof option === 'string') {
|
|
57
|
+
optArray.items.push(new PdfString(option));
|
|
58
|
+
}
|
|
59
|
+
else if (option.label === option.value) {
|
|
60
|
+
optArray.items.push(new PdfString(option.value));
|
|
61
|
+
}
|
|
62
|
+
else {
|
|
63
|
+
const pair = new PdfArray();
|
|
64
|
+
pair.items.push(new PdfString(option.value));
|
|
65
|
+
pair.items.push(new PdfString(option.label));
|
|
66
|
+
optArray.items.push(pair);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
this.content.set('Opt', optArray);
|
|
70
|
+
}
|
|
71
|
+
generateAppearance(options) {
|
|
72
|
+
const rect = this.rect;
|
|
73
|
+
if (!rect || rect.length !== 4)
|
|
74
|
+
return false;
|
|
75
|
+
const da = this.defaultAppearance;
|
|
76
|
+
if (!da)
|
|
77
|
+
return false;
|
|
78
|
+
const value = this.value;
|
|
79
|
+
if (!value)
|
|
80
|
+
return false;
|
|
81
|
+
const parsed = PdfDefaultAppearance.parse(da);
|
|
82
|
+
if (!parsed)
|
|
83
|
+
return false;
|
|
84
|
+
let fontResources;
|
|
85
|
+
const drFontValue = this.form?.defaultResources?.get('Font');
|
|
86
|
+
const drFonts = drFontValue instanceof PdfDictionary ? drFontValue : undefined;
|
|
87
|
+
const daFontRef = this.form?.fontRefs?.get(parsed.fontName);
|
|
88
|
+
if (drFonts || daFontRef) {
|
|
89
|
+
// Build a fresh font dict using clean PdfObjectReferences (no
|
|
90
|
+
// pre/postTokens inherited from the original parse context).
|
|
91
|
+
const fontDict = new PdfDictionary();
|
|
92
|
+
if (drFonts) {
|
|
93
|
+
for (const [key, val] of drFonts.entries()) {
|
|
94
|
+
if (val instanceof PdfObjectReference) {
|
|
95
|
+
fontDict.set(key, new PdfObjectReference(val.objectNumber, val.generationNumber));
|
|
96
|
+
}
|
|
97
|
+
else if (val != null) {
|
|
98
|
+
fontDict.set(key, val);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
if (daFontRef && !fontDict.has(parsed.fontName)) {
|
|
103
|
+
fontDict.set(parsed.fontName, new PdfObjectReference(daFontRef.objectNumber, daFontRef.generationNumber));
|
|
104
|
+
}
|
|
105
|
+
fontResources = new PdfDictionary();
|
|
106
|
+
fontResources.set('Font', fontDict);
|
|
107
|
+
}
|
|
108
|
+
const isUnicode = this.form?.isFontUnicode(parsed.fontName) ?? false;
|
|
109
|
+
const encodingMap = this.form?.fontEncodingMaps?.get(parsed.fontName);
|
|
110
|
+
const reverseEncodingMap = encodingMap
|
|
111
|
+
? new Map(Array.from(encodingMap, ([code, char]) => [char, code]))
|
|
112
|
+
: undefined;
|
|
113
|
+
this._appearanceStream = new PdfChoiceAppearanceStream({
|
|
114
|
+
rect: rect,
|
|
115
|
+
value,
|
|
116
|
+
da: parsed,
|
|
117
|
+
flags: this.flags,
|
|
118
|
+
fontResources,
|
|
119
|
+
isUnicode,
|
|
120
|
+
reverseEncodingMap,
|
|
121
|
+
displayOptions: this.options.map((opt) => opt.label),
|
|
122
|
+
selectedIndex: this.selectedIndex,
|
|
123
|
+
});
|
|
124
|
+
if (options?.makeReadOnly) {
|
|
125
|
+
this.readOnly = true;
|
|
126
|
+
this.print = true;
|
|
127
|
+
this.noZoom = true;
|
|
128
|
+
}
|
|
129
|
+
return true;
|
|
130
|
+
}
|
|
131
|
+
}
|
|
@@ -1,14 +1,13 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { PdfNumber } from '../../core/objects/pdf-number.js';
|
|
2
2
|
/**
|
|
3
3
|
* Field-specific Ff flag accessors for form fields.
|
|
4
4
|
* These are separate from annotation flags (F field).
|
|
5
|
+
* Extends PdfNumber so it can be stored directly in a PDF dictionary.
|
|
5
6
|
*/
|
|
6
|
-
export declare class PdfFormFieldFlags {
|
|
7
|
-
|
|
8
|
-
parentDict?: PdfDictionary;
|
|
9
|
-
constructor(dict: PdfDictionary, parentDict?: PdfDictionary);
|
|
7
|
+
export declare class PdfFormFieldFlags extends PdfNumber {
|
|
8
|
+
constructor(value?: number | PdfNumber | PdfFormFieldFlags);
|
|
10
9
|
get flags(): number;
|
|
11
|
-
set flags(
|
|
10
|
+
set flags(v: number | PdfFormFieldFlags);
|
|
12
11
|
private getFlag;
|
|
13
12
|
private setFlag;
|
|
14
13
|
get readOnly(): boolean;
|
|
@@ -2,32 +2,26 @@ import { PdfNumber } from '../../core/objects/pdf-number.js';
|
|
|
2
2
|
/**
|
|
3
3
|
* Field-specific Ff flag accessors for form fields.
|
|
4
4
|
* These are separate from annotation flags (F field).
|
|
5
|
+
* Extends PdfNumber so it can be stored directly in a PDF dictionary.
|
|
5
6
|
*/
|
|
6
|
-
export class PdfFormFieldFlags {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
this.
|
|
11
|
-
|
|
7
|
+
export class PdfFormFieldFlags extends PdfNumber {
|
|
8
|
+
constructor(value = 0) {
|
|
9
|
+
super(value);
|
|
10
|
+
this.preTokens = typeof value === 'number' ? undefined : value.preTokens;
|
|
11
|
+
this.postTokens =
|
|
12
|
+
typeof value === 'number' ? undefined : value.postTokens;
|
|
12
13
|
}
|
|
13
14
|
get flags() {
|
|
14
|
-
return
|
|
15
|
-
this.parentDict?.get('Ff')?.as(PdfNumber)?.value ??
|
|
16
|
-
0);
|
|
15
|
+
return this.value;
|
|
17
16
|
}
|
|
18
|
-
set flags(
|
|
19
|
-
this.
|
|
17
|
+
set flags(v) {
|
|
18
|
+
this.value = v instanceof PdfFormFieldFlags ? v.value : v;
|
|
20
19
|
}
|
|
21
20
|
getFlag(bit) {
|
|
22
21
|
return (this.flags & bit) !== 0;
|
|
23
22
|
}
|
|
24
|
-
setFlag(bit,
|
|
25
|
-
|
|
26
|
-
this.flags = this.flags | bit;
|
|
27
|
-
}
|
|
28
|
-
else {
|
|
29
|
-
this.flags = this.flags & ~bit;
|
|
30
|
-
}
|
|
23
|
+
setFlag(bit, val) {
|
|
24
|
+
this.flags = val ? this.flags | bit : this.flags & ~bit;
|
|
31
25
|
}
|
|
32
26
|
get readOnly() {
|
|
33
27
|
return this.getFlag(1);
|
|
@@ -3,9 +3,10 @@ import { PdfObjectReference } from '../../core/objects/pdf-object-reference.js';
|
|
|
3
3
|
import { PdfIndirectObject } from '../../core/objects/pdf-indirect-object.js';
|
|
4
4
|
import { PdfFont } from '../../fonts/pdf-font.js';
|
|
5
5
|
import { PdfStream } from '../../core/objects/pdf-stream.js';
|
|
6
|
-
import { PdfWidgetAnnotation } from '../../annotations/
|
|
7
|
-
import type { PdfAppearanceStream } from '../appearance/
|
|
6
|
+
import { PdfWidgetAnnotation } from '../../annotations/pdf-widget-annotation.js';
|
|
7
|
+
import type { PdfAppearanceStream } from '../appearance/pdf-appearance-stream.js';
|
|
8
8
|
import type { FormContext, PdfFieldType } from './types.js';
|
|
9
|
+
import { PdfFormFieldFlags } from './pdf-form-field-flags.js';
|
|
9
10
|
/**
|
|
10
11
|
* Abstract base form field class. Extends PdfWidgetAnnotation with form-specific properties:
|
|
11
12
|
* FT, V, DA, Ff, T (name), field hierarchy (parent/children/siblings).
|
|
@@ -36,17 +37,22 @@ export declare abstract class PdfFormField extends PdfWidgetAnnotation {
|
|
|
36
37
|
set defaultValue(val: string);
|
|
37
38
|
get value(): string;
|
|
38
39
|
set value(val: string | PdfString);
|
|
40
|
+
/**
|
|
41
|
+
* Writes the value to the dictionary. Returns true if appearance generation
|
|
42
|
+
* should proceed, false to skip it (e.g. when value was cleared).
|
|
43
|
+
* Override in subclasses to change the stored representation.
|
|
44
|
+
*/
|
|
45
|
+
protected _storeValue(val: string | PdfString, fieldParent: PdfFormField | undefined): boolean;
|
|
46
|
+
protected tryGenerateAppearance(field: PdfFormField): void;
|
|
39
47
|
get checked(): boolean;
|
|
40
|
-
set checked(
|
|
48
|
+
set checked(_isChecked: boolean);
|
|
41
49
|
get fontSize(): number | null;
|
|
42
50
|
set fontSize(size: number);
|
|
43
51
|
get fontName(): string | null;
|
|
44
52
|
set fontName(fontName: string);
|
|
45
53
|
set font(font: PdfFont | null);
|
|
46
|
-
get flags():
|
|
47
|
-
set flags(
|
|
48
|
-
private getFlag;
|
|
49
|
-
private setFlag;
|
|
54
|
+
get flags(): PdfFormFieldFlags;
|
|
55
|
+
set flags(v: PdfFormFieldFlags);
|
|
50
56
|
get readOnly(): boolean;
|
|
51
57
|
set readOnly(v: boolean);
|
|
52
58
|
get required(): boolean;
|
|
@@ -82,8 +88,6 @@ export declare abstract class PdfFormField extends PdfWidgetAnnotation {
|
|
|
82
88
|
set commitOnSelChange(v: boolean);
|
|
83
89
|
get quadding(): number;
|
|
84
90
|
set quadding(q: number);
|
|
85
|
-
get options(): string[];
|
|
86
|
-
set options(options: string[]);
|
|
87
91
|
get defaultAppearance(): string | null;
|
|
88
92
|
set defaultAppearance(da: string);
|
|
89
93
|
get maxLen(): number | null;
|
|
@@ -99,10 +103,10 @@ export declare abstract class PdfFormField extends PdfWidgetAnnotation {
|
|
|
99
103
|
primary: PdfAppearanceStream;
|
|
100
104
|
secondary?: PdfAppearanceStream;
|
|
101
105
|
} | undefined;
|
|
102
|
-
setAppearanceReference(appearanceStreamRef: PdfObjectReference,
|
|
106
|
+
setAppearanceReference(appearanceStreamRef: PdfObjectReference, _appearanceStreamYesRef?: PdfObjectReference): void;
|
|
103
107
|
private static _fallbackCtor?;
|
|
104
108
|
private static _registry;
|
|
105
|
-
static registerFieldType(ft:
|
|
109
|
+
static registerFieldType(ft: 'Sig' | 'Btn' | 'Tx' | 'Ch', ctor: new (options?: {
|
|
106
110
|
other?: PdfIndirectObject;
|
|
107
111
|
form?: FormContext<PdfFormField>;
|
|
108
112
|
parent?: PdfFormField;
|