pdf-lite 1.5.0 → 1.6.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/EXAMPLES.md +51 -70
- package/README.md +1 -1
- package/dist/acroform/appearance/pdf-button-appearance-stream.d.ts +1 -1
- package/dist/acroform/appearance/pdf-button-appearance-stream.js +6 -2
- package/dist/acroform/fields/pdf-button-form-field.d.ts +0 -9
- package/dist/acroform/fields/pdf-button-form-field.js +7 -39
- package/dist/acroform/fields/pdf-choice-form-field.d.ts +2 -1
- package/dist/acroform/fields/pdf-choice-form-field.js +19 -38
- package/dist/acroform/fields/pdf-form-field.d.ts +27 -32
- package/dist/acroform/fields/pdf-form-field.js +180 -94
- package/dist/acroform/fields/pdf-text-form-field.js +6 -33
- package/dist/acroform/fields/types.d.ts +1 -1
- package/dist/acroform/index.d.ts +0 -2
- package/dist/acroform/index.js +0 -2
- package/dist/acroform/pdf-acro-form.d.ts +12 -36
- package/dist/acroform/pdf-acro-form.js +111 -201
- package/dist/acroform/xfa/pdf-xfa-data.d.ts +4 -3
- package/dist/acroform/xfa/pdf-xfa-data.js +16 -12
- package/dist/acroform/xfa/pdf-xfa-form.d.ts +9 -4
- package/dist/acroform/xfa/pdf-xfa-form.js +17 -39
- package/dist/annotations/index.d.ts +0 -1
- package/dist/annotations/index.js +0 -1
- package/dist/annotations/pdf-annotation.d.ts +7 -2
- package/dist/annotations/pdf-annotation.js +30 -19
- package/dist/annotations/pdf-default-resources.d.ts +11 -0
- package/dist/annotations/pdf-default-resources.js +3 -0
- package/dist/core/decoder.js +1 -1
- package/dist/core/objects/pdf-array.d.ts +8 -1
- package/dist/core/objects/pdf-array.js +31 -0
- package/dist/core/objects/pdf-dictionary.d.ts +2 -0
- package/dist/core/objects/pdf-dictionary.js +14 -7
- package/dist/core/objects/pdf-hexadecimal.d.ts +1 -0
- package/dist/core/objects/pdf-hexadecimal.js +3 -3
- package/dist/core/objects/pdf-indirect-object.d.ts +18 -9
- package/dist/core/objects/pdf-indirect-object.js +75 -16
- package/dist/core/objects/pdf-number.d.ts +1 -0
- package/dist/core/objects/pdf-number.js +5 -4
- package/dist/core/objects/pdf-object-reference.d.ts +8 -1
- package/dist/core/objects/pdf-object-reference.js +14 -0
- package/dist/core/objects/pdf-object.d.ts +14 -0
- package/dist/core/objects/pdf-object.js +36 -0
- package/dist/core/objects/pdf-start-xref.d.ts +1 -0
- package/dist/core/objects/pdf-start-xref.js +4 -0
- package/dist/core/objects/pdf-stream.d.ts +43 -7
- package/dist/core/objects/pdf-stream.js +278 -24
- package/dist/core/objects/pdf-string.d.ts +1 -0
- package/dist/core/objects/pdf-string.js +3 -6
- package/dist/core/objects/pdf-trailer.d.ts +1 -0
- package/dist/core/objects/pdf-trailer.js +6 -3
- package/dist/core/objects/pdf-xref-table.js +1 -1
- package/dist/core/ref.d.ts +3 -1
- package/dist/core/ref.js +8 -5
- package/dist/core/tokens/token.d.ts +2 -1
- package/dist/core/tokens/token.js +3 -0
- package/dist/fonts/index.d.ts +0 -1
- package/dist/fonts/index.js +0 -1
- package/dist/fonts/pdf-font.d.ts +32 -27
- package/dist/fonts/pdf-font.js +115 -77
- package/dist/pdf/index.d.ts +2 -0
- package/dist/pdf/index.js +2 -0
- package/dist/pdf/pdf-document.d.ts +61 -37
- package/dist/pdf/pdf-document.js +314 -120
- package/dist/pdf/pdf-page.d.ts +50 -0
- package/dist/pdf/pdf-page.js +144 -0
- package/dist/pdf/pdf-pages.d.ts +28 -0
- package/dist/pdf/pdf-pages.js +94 -0
- package/dist/pdf/pdf-reader.d.ts +5 -1
- package/dist/pdf/pdf-reader.js +36 -2
- package/dist/pdf/pdf-revision.d.ts +3 -3
- package/dist/pdf/pdf-revision.js +7 -7
- package/dist/pdf/pdf-xref-lookup.js +34 -14
- package/dist/signing/document-security-store.d.ts +14 -17
- package/dist/signing/document-security-store.js +19 -34
- package/dist/signing/signer.d.ts +23 -8
- package/dist/signing/signer.js +51 -17
- package/dist/utils/index.d.ts +0 -1
- package/dist/utils/index.js +0 -1
- package/dist/utils/needsCentralWhitespace.d.ts +10 -0
- package/dist/utils/needsCentralWhitespace.js +34 -0
- package/package.json +3 -3
- package/dist/acroform/acroform.d.ts +0 -9
- package/dist/acroform/acroform.js +0 -7
- package/dist/acroform/manager.d.ts +0 -37
- package/dist/acroform/manager.js +0 -57
- package/dist/acroform/pdf-font-encoding-cache.d.ts +0 -27
- package/dist/acroform/pdf-font-encoding-cache.js +0 -188
- package/dist/annotations/pdf-annotation-writer.d.ts +0 -20
- package/dist/annotations/pdf-annotation-writer.js +0 -76
- package/dist/fonts/manager.d.ts +0 -127
- package/dist/fonts/manager.js +0 -378
- package/dist/utils/predictors.d.ts +0 -113
- package/dist/utils/predictors.js +0 -279
package/EXAMPLES.md
CHANGED
|
@@ -10,38 +10,11 @@ import { PdfArray } from 'pdf-lite/core/objects/pdf-array'
|
|
|
10
10
|
import { PdfDictionary } from 'pdf-lite/core/objects/pdf-dictionary'
|
|
11
11
|
import { PdfIndirectObject } from 'pdf-lite/core/objects/pdf-indirect-object'
|
|
12
12
|
import { PdfName } from 'pdf-lite/core/objects/pdf-name'
|
|
13
|
-
import { PdfNumber } from 'pdf-lite/core/objects/pdf-number'
|
|
14
13
|
import { PdfObjectReference } from 'pdf-lite/core/objects/pdf-object-reference'
|
|
15
14
|
import { PdfStream } from 'pdf-lite/core/objects/pdf-stream'
|
|
16
15
|
import { PdfDocument } from 'pdf-lite/pdf/pdf-document'
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
contentStreamRef: PdfObjectReference,
|
|
20
|
-
): PdfIndirectObject<PdfDictionary> {
|
|
21
|
-
const pageDict = new PdfDictionary()
|
|
22
|
-
pageDict.set('Type', new PdfName('Page'))
|
|
23
|
-
pageDict.set(
|
|
24
|
-
'MediaBox',
|
|
25
|
-
new PdfArray([
|
|
26
|
-
new PdfNumber(0),
|
|
27
|
-
new PdfNumber(0),
|
|
28
|
-
new PdfNumber(612),
|
|
29
|
-
new PdfNumber(792),
|
|
30
|
-
]),
|
|
31
|
-
)
|
|
32
|
-
pageDict.set('Contents', contentStreamRef)
|
|
33
|
-
return new PdfIndirectObject({ content: pageDict })
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
function createPages(
|
|
37
|
-
pages: PdfIndirectObject<PdfDictionary>[],
|
|
38
|
-
): PdfIndirectObject<PdfDictionary> {
|
|
39
|
-
const pagesDict = new PdfDictionary()
|
|
40
|
-
pagesDict.set('Type', new PdfName('Pages'))
|
|
41
|
-
pagesDict.set('Kids', new PdfArray(pages.map((x) => x.reference)))
|
|
42
|
-
pagesDict.set('Count', new PdfNumber(pages.length))
|
|
43
|
-
return new PdfIndirectObject({ content: pagesDict })
|
|
44
|
-
}
|
|
16
|
+
import { PdfPage } from 'pdf-lite/pdf/pdf-page'
|
|
17
|
+
import { PdfPages } from 'pdf-lite/pdf/pdf-pages'
|
|
45
18
|
|
|
46
19
|
function createCatalog(
|
|
47
20
|
pagesRef: PdfObjectReference,
|
|
@@ -89,16 +62,18 @@ const contentStream = new PdfIndirectObject({
|
|
|
89
62
|
}),
|
|
90
63
|
})
|
|
91
64
|
|
|
92
|
-
// Create a page
|
|
93
|
-
const page =
|
|
94
|
-
|
|
95
|
-
page.
|
|
65
|
+
// Create a page using PdfPage
|
|
66
|
+
const page = new PdfPage()
|
|
67
|
+
page.mediaBox = [0, 0, 612, 792]
|
|
68
|
+
page.contents = contentStream.reference
|
|
69
|
+
page.resources = resources.reference
|
|
96
70
|
document.add(page)
|
|
97
71
|
|
|
98
|
-
// Create pages collection
|
|
99
|
-
const pages =
|
|
100
|
-
|
|
101
|
-
|
|
72
|
+
// Create pages collection using PdfPages
|
|
73
|
+
const pages = new PdfPages()
|
|
74
|
+
pages.kids = new PdfArray([page.reference])
|
|
75
|
+
pages.count = 1
|
|
76
|
+
page.parent = pages
|
|
102
77
|
document.add(pages)
|
|
103
78
|
|
|
104
79
|
// Create catalog
|
|
@@ -109,7 +84,7 @@ document.add(catalog)
|
|
|
109
84
|
document.trailerDict.set('Root', catalog.reference)
|
|
110
85
|
|
|
111
86
|
document.add(contentStream)
|
|
112
|
-
await document.
|
|
87
|
+
await document.finalize()
|
|
113
88
|
|
|
114
89
|
const file = `${import.meta.dirname}/tmp/created.pdf`
|
|
115
90
|
console.log(`Writing PDF to: ${file}`)
|
|
@@ -225,7 +200,7 @@ document.add(catalog)
|
|
|
225
200
|
document.trailerDict.set('Root', catalog.reference)
|
|
226
201
|
|
|
227
202
|
document.add(contentStream)
|
|
228
|
-
await document.
|
|
203
|
+
await document.finalize()
|
|
229
204
|
|
|
230
205
|
document.securityHandler = new PdfV2SecurityHandler({
|
|
231
206
|
password: 'up',
|
|
@@ -577,14 +552,7 @@ document.add(catalog)
|
|
|
577
552
|
// Set the catalog as the root
|
|
578
553
|
document.trailerDict.set('Root', catalog.reference)
|
|
579
554
|
|
|
580
|
-
|
|
581
|
-
// This ensures the ByteRange is calculated correctly for each signature
|
|
582
|
-
allSignatures.forEach((sig) => {
|
|
583
|
-
document.startNewRevision()
|
|
584
|
-
document.add(sig)
|
|
585
|
-
})
|
|
586
|
-
|
|
587
|
-
await document.commit()
|
|
555
|
+
await document.finalize()
|
|
588
556
|
|
|
589
557
|
const tmpFolder = `${import.meta.dirname}/tmp`
|
|
590
558
|
await fs.mkdir(tmpFolder, { recursive: true })
|
|
@@ -694,7 +662,7 @@ document.add(catalog)
|
|
|
694
662
|
document.trailerDict.set('Root', catalog.reference)
|
|
695
663
|
document.add(contentStream)
|
|
696
664
|
|
|
697
|
-
await document.
|
|
665
|
+
await document.finalize()
|
|
698
666
|
// Save the original PDF
|
|
699
667
|
const originalPdfPath = `${tmpFolder}/original.pdf`
|
|
700
668
|
await fs.writeFile(originalPdfPath, document.toBytes())
|
|
@@ -706,7 +674,9 @@ console.log('\nStep 2: Loading PDF and performing incremental update...')
|
|
|
706
674
|
|
|
707
675
|
// Read the existing PDF
|
|
708
676
|
const existingPdfBytes = await fs.readFile(originalPdfPath)
|
|
709
|
-
const loadedDocument = await PdfDocument.fromBytes([existingPdfBytes]
|
|
677
|
+
const loadedDocument = await PdfDocument.fromBytes([existingPdfBytes], {
|
|
678
|
+
incremental: true,
|
|
679
|
+
})
|
|
710
680
|
|
|
711
681
|
// Lock existing revisions to enable incremental mode
|
|
712
682
|
// This ensures changes are added as new revisions instead of modifying existing ones
|
|
@@ -726,7 +696,7 @@ const newContentStream = new PdfIndirectObject({
|
|
|
726
696
|
|
|
727
697
|
// Add the new content to the document
|
|
728
698
|
loadedDocument.add(newContentStream)
|
|
729
|
-
await loadedDocument.
|
|
699
|
+
await loadedDocument.finalize()
|
|
730
700
|
|
|
731
701
|
// Save the incrementally updated PDF
|
|
732
702
|
const updatedPdfPath = `${tmpFolder}/incremental-update.pdf`
|
|
@@ -768,7 +738,9 @@ console.log(`Original content preserved: ${originalBytesMatch ? 'Yes' : 'No'}`)
|
|
|
768
738
|
// Step 4: Add another incremental revision
|
|
769
739
|
console.log('\nStep 4: Adding another incremental revision...')
|
|
770
740
|
|
|
771
|
-
const secondUpdate = await PdfDocument.fromBytes([updatedPdfBytes]
|
|
741
|
+
const secondUpdate = await PdfDocument.fromBytes([updatedPdfBytes], {
|
|
742
|
+
incremental: true,
|
|
743
|
+
})
|
|
772
744
|
secondUpdate.setIncremental(true)
|
|
773
745
|
|
|
774
746
|
const thirdRevisionContent = new PdfIndirectObject({
|
|
@@ -780,7 +752,7 @@ const thirdRevisionContent = new PdfIndirectObject({
|
|
|
780
752
|
})
|
|
781
753
|
|
|
782
754
|
secondUpdate.add(thirdRevisionContent)
|
|
783
|
-
await secondUpdate.
|
|
755
|
+
await secondUpdate.finalize()
|
|
784
756
|
|
|
785
757
|
const multiRevisionPdfPath = `${tmpFolder}/multi-revision.pdf`
|
|
786
758
|
await fs.writeFile(multiRevisionPdfPath, secondUpdate.toBytes())
|
|
@@ -1092,7 +1064,7 @@ document.add(catalog)
|
|
|
1092
1064
|
// Set the catalog as the root
|
|
1093
1065
|
document.trailerDict.set('Root', catalog.reference)
|
|
1094
1066
|
|
|
1095
|
-
await document.
|
|
1067
|
+
await document.finalize()
|
|
1096
1068
|
|
|
1097
1069
|
// Save the empty form
|
|
1098
1070
|
// This demonstrates creating a blank form that users can fill in
|
|
@@ -1109,7 +1081,7 @@ console.log('Created form-empty.pdf with empty form fields')
|
|
|
1109
1081
|
const emptyFormBytes = await fs.readFile(`${tmpFolder}/form-empty.pdf`)
|
|
1110
1082
|
const filledDocument = await PdfDocument.fromBytes([emptyFormBytes])
|
|
1111
1083
|
|
|
1112
|
-
const acroform =
|
|
1084
|
+
const acroform = filledDocument.acroform
|
|
1113
1085
|
if (!acroform) {
|
|
1114
1086
|
throw new Error('No AcroForm found in the document')
|
|
1115
1087
|
}
|
|
@@ -1119,7 +1091,6 @@ acroform.importData({
|
|
|
1119
1091
|
phone: '+1 (555) 123-4567',
|
|
1120
1092
|
subscribe: 'Off', // For checkbox, use the "Yes/Off" value
|
|
1121
1093
|
})
|
|
1122
|
-
await filledDocument.acroForm.write(acroform)
|
|
1123
1094
|
|
|
1124
1095
|
// Save the filled form
|
|
1125
1096
|
await fs.writeFile(`${tmpFolder}/form-filled.pdf`, filledDocument.toBytes())
|
|
@@ -1808,7 +1779,7 @@ allSignatures.forEach((sig) => {
|
|
|
1808
1779
|
document.add(sig)
|
|
1809
1780
|
})
|
|
1810
1781
|
|
|
1811
|
-
await document.
|
|
1782
|
+
await document.finalize()
|
|
1812
1783
|
|
|
1813
1784
|
const documentBytes = document.toBytes()
|
|
1814
1785
|
const newDocument = await PdfDocument.fromBytes([documentBytes])
|
|
@@ -1885,7 +1856,7 @@ async function main() {
|
|
|
1885
1856
|
|
|
1886
1857
|
document.add(pages, catalog)
|
|
1887
1858
|
document.trailerDict.set('Root', catalog.reference)
|
|
1888
|
-
await document.
|
|
1859
|
+
await document.finalize()
|
|
1889
1860
|
|
|
1890
1861
|
// Build content stream with different fonts
|
|
1891
1862
|
// F1=Helvetica-Bold, F2=Times-Roman, F3=Courier, F4=Roboto
|
|
@@ -1930,11 +1901,13 @@ async function main() {
|
|
|
1930
1901
|
}),
|
|
1931
1902
|
})
|
|
1932
1903
|
|
|
1933
|
-
//
|
|
1934
|
-
const helveticaBold =
|
|
1935
|
-
|
|
1936
|
-
const timesRoman =
|
|
1937
|
-
|
|
1904
|
+
// Create standard fonts and assign resource names to match the content stream
|
|
1905
|
+
const helveticaBold = PdfFont.fromStandardFont('Helvetica-Bold')
|
|
1906
|
+
helveticaBold.resourceName = 'F1'
|
|
1907
|
+
const timesRoman = PdfFont.fromStandardFont('Times-Roman')
|
|
1908
|
+
timesRoman.resourceName = 'F2'
|
|
1909
|
+
const courier = PdfFont.fromStandardFont('Courier')
|
|
1910
|
+
courier.resourceName = 'F3'
|
|
1938
1911
|
|
|
1939
1912
|
console.log(
|
|
1940
1913
|
`Embedded standard fonts: ${helveticaBold}, ${timesRoman}, ${courier}`,
|
|
@@ -1960,6 +1933,7 @@ async function main() {
|
|
|
1960
1933
|
// - Creates a ready-to-use PdfFont instance
|
|
1961
1934
|
// - Throws descriptive errors for unsupported formats (WOFF2, CFF-based OTF)
|
|
1962
1935
|
const robotoFont = PdfFont.fromBytes(fontData)
|
|
1936
|
+
robotoFont.resourceName = 'F4'
|
|
1963
1937
|
|
|
1964
1938
|
console.log(
|
|
1965
1939
|
`Created PdfFont from bytes - Font name: ${robotoFont.fontName}`,
|
|
@@ -1969,15 +1943,22 @@ async function main() {
|
|
|
1969
1943
|
` Embedded font data preserved: ${robotoFont.fontData ? 'Yes' : 'No'}`,
|
|
1970
1944
|
)
|
|
1971
1945
|
|
|
1972
|
-
//
|
|
1973
|
-
|
|
1974
|
-
// - Assigns a resource name (F1, F2, F3, etc.)
|
|
1975
|
-
// - Creates the container indirect object
|
|
1976
|
-
// - Adds the font to the /Pages node Resources dictionary
|
|
1977
|
-
// - All child pages inherit these fonts (even pages added later!)
|
|
1978
|
-
await document.fonts.write(robotoFont)
|
|
1946
|
+
// Add all fonts to the document
|
|
1947
|
+
document.add(helveticaBold, timesRoman, courier, robotoFont)
|
|
1979
1948
|
console.log(`Embedded custom font in PDF: ${robotoFont}`)
|
|
1980
1949
|
|
|
1950
|
+
// Build a Font resource dictionary mapping resource names to font references
|
|
1951
|
+
const fontDict = new PdfDictionary()
|
|
1952
|
+
fontDict.set(helveticaBold.resourceName, helveticaBold.reference)
|
|
1953
|
+
fontDict.set(timesRoman.resourceName, timesRoman.reference)
|
|
1954
|
+
fontDict.set(courier.resourceName, courier.reference)
|
|
1955
|
+
fontDict.set(robotoFont.resourceName, robotoFont.reference)
|
|
1956
|
+
|
|
1957
|
+
// Add font resources to the /Pages node so all child pages inherit them
|
|
1958
|
+
const resourcesDict = new PdfDictionary()
|
|
1959
|
+
resourcesDict.set('Font', fontDict)
|
|
1960
|
+
pages.content.set('Resources', resourcesDict)
|
|
1961
|
+
|
|
1981
1962
|
console.log(`\nFont resource mappings:`)
|
|
1982
1963
|
console.log(` ${helveticaBold.resourceName} = Helvetica-Bold`)
|
|
1983
1964
|
console.log(` ${timesRoman.resourceName} = Times-Roman`)
|
|
@@ -1992,7 +1973,7 @@ async function main() {
|
|
|
1992
1973
|
pages.content.set('Count', new PdfNumber(1))
|
|
1993
1974
|
|
|
1994
1975
|
document.add(contentStream, page)
|
|
1995
|
-
await document.
|
|
1976
|
+
await document.finalize()
|
|
1996
1977
|
|
|
1997
1978
|
console.log(`\nFont resource mappings:`)
|
|
1998
1979
|
console.log(` ${helveticaBold.resourceName} = Helvetica-Bold`)
|
package/README.md
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
A low-level, minimal-dependency, type-safe PDF library that works in the browser and Node.js.
|
|
6
6
|
|
|
7
|
-
> **Note**: This library is actively developed and may not support all PDF features yet. However, it is designed to be extensible and can be improved over time.
|
|
7
|
+
> **Note**: This library is actively developed and may not support all PDF features yet. However, it is designed to be extensible and can be improved over time. I would also not expect the API to be stable until at least version 2.0 as a lot of features are still being added and the API is evolving.
|
|
8
8
|
|
|
9
9
|
PRs and issues are welcome!
|
|
10
10
|
|
|
@@ -9,5 +9,5 @@ export declare class PdfButtonAppearanceStream extends PdfAppearanceStream {
|
|
|
9
9
|
height: number;
|
|
10
10
|
contentStream: string;
|
|
11
11
|
});
|
|
12
|
-
static buildYesContent(width: number, height: number, flags: number | PdfFormFieldFlags):
|
|
12
|
+
static buildYesContent(width: number, height: number, flags: number | PdfFormFieldFlags): PdfButtonAppearanceStream;
|
|
13
13
|
}
|
|
@@ -10,7 +10,7 @@ export class PdfButtonAppearanceStream extends PdfAppearanceStream {
|
|
|
10
10
|
constructor(ctx) {
|
|
11
11
|
const resources = new PdfDictionary();
|
|
12
12
|
const fonts = new PdfDictionary();
|
|
13
|
-
fonts.set('ZaDb', PdfFont.ZAPF_DINGBATS);
|
|
13
|
+
fonts.set('ZaDb', PdfFont.ZAPF_DINGBATS.dict.clone());
|
|
14
14
|
resources.set('Font', fonts);
|
|
15
15
|
super({
|
|
16
16
|
width: ctx.width,
|
|
@@ -49,6 +49,10 @@ export class PdfButtonAppearanceStream extends PdfAppearanceStream {
|
|
|
49
49
|
g.endText();
|
|
50
50
|
g.restore();
|
|
51
51
|
}
|
|
52
|
-
return
|
|
52
|
+
return new PdfButtonAppearanceStream({
|
|
53
|
+
width,
|
|
54
|
+
height,
|
|
55
|
+
contentStream: g.build(),
|
|
56
|
+
});
|
|
53
57
|
}
|
|
54
58
|
}
|
|
@@ -1,8 +1,5 @@
|
|
|
1
1
|
import { PdfFormField } from './pdf-form-field.js';
|
|
2
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
3
|
/**
|
|
7
4
|
* Button form field subtype (checkboxes, radio buttons, push buttons).
|
|
8
5
|
*/
|
|
@@ -11,12 +8,6 @@ export declare class PdfButtonFormField extends PdfFormField {
|
|
|
11
8
|
protected _storeValue(val: string | PdfString, fieldParent: PdfFormField | undefined): boolean;
|
|
12
9
|
get checked(): boolean;
|
|
13
10
|
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
11
|
generateAppearance(options?: {
|
|
21
12
|
makeReadOnly?: boolean;
|
|
22
13
|
}): boolean;
|
|
@@ -2,7 +2,6 @@ import { PdfFormField } from './pdf-form-field.js';
|
|
|
2
2
|
import { PdfButtonAppearanceStream } from '../appearance/pdf-button-appearance-stream.js';
|
|
3
3
|
import { PdfName } from '../../core/objects/pdf-name.js';
|
|
4
4
|
import { PdfString } from '../../core/objects/pdf-string.js';
|
|
5
|
-
import { PdfDictionary } from '../../core/objects/pdf-dictionary.js';
|
|
6
5
|
/**
|
|
7
6
|
* Button form field subtype (checkboxes, radio buttons, push buttons).
|
|
8
7
|
*/
|
|
@@ -41,36 +40,6 @@ export class PdfButtonFormField extends PdfFormField {
|
|
|
41
40
|
this.content.set('AS', new PdfName('Off'));
|
|
42
41
|
}
|
|
43
42
|
}
|
|
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
43
|
generateAppearance(options) {
|
|
75
44
|
const rect = this.rect;
|
|
76
45
|
if (!rect || rect.length !== 4)
|
|
@@ -78,19 +47,18 @@ export class PdfButtonFormField extends PdfFormField {
|
|
|
78
47
|
const [x1, y1, x2, y2] = rect;
|
|
79
48
|
const width = x2 - x1;
|
|
80
49
|
const height = y2 - y1;
|
|
81
|
-
this._appearanceStream = new PdfButtonAppearanceStream({
|
|
82
|
-
width,
|
|
83
|
-
height,
|
|
84
|
-
contentStream: '',
|
|
85
|
-
});
|
|
86
50
|
// Merge own flags with parent flags so inherited bits (e.g. Radio) are
|
|
87
51
|
// not lost when a child widget has its own Ff entry (even Ff: 0).
|
|
88
52
|
const effectiveFlags = this.flags.flags | (this.parent?.flags?.flags ?? 0);
|
|
89
|
-
const
|
|
90
|
-
|
|
53
|
+
const yesAppearance = PdfButtonAppearanceStream.buildYesContent(width, height, effectiveFlags);
|
|
54
|
+
const noAppearance = new PdfButtonAppearanceStream({
|
|
91
55
|
width,
|
|
92
56
|
height,
|
|
93
|
-
contentStream:
|
|
57
|
+
contentStream: '',
|
|
58
|
+
});
|
|
59
|
+
this.setAppearanceStream({
|
|
60
|
+
Yes: yesAppearance,
|
|
61
|
+
Off: noAppearance,
|
|
94
62
|
});
|
|
95
63
|
if (options?.makeReadOnly) {
|
|
96
64
|
this.readOnly = true;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { PdfFormField } from './pdf-form-field.js';
|
|
2
|
+
import { PdfObjectReference } from '../../core/objects/pdf-object-reference.js';
|
|
2
3
|
/**
|
|
3
4
|
* Choice form field subtype (dropdowns, list boxes).
|
|
4
5
|
*/
|
|
@@ -11,7 +12,7 @@ export declare class PdfChoiceFormField extends PdfFormField {
|
|
|
11
12
|
set options(values: {
|
|
12
13
|
label: string;
|
|
13
14
|
value: string;
|
|
14
|
-
}[] | string[] | undefined);
|
|
15
|
+
}[] | string[] | PdfObjectReference | undefined);
|
|
15
16
|
generateAppearance(options?: {
|
|
16
17
|
makeReadOnly?: boolean;
|
|
17
18
|
}): boolean;
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { PdfFormField } from './pdf-form-field.js';
|
|
2
2
|
import { PdfDefaultAppearance } from './pdf-default-appearance.js';
|
|
3
3
|
import { PdfChoiceAppearanceStream } from '../appearance/pdf-choice-appearance-stream.js';
|
|
4
|
-
import { PdfDictionary } from '../../core/objects/pdf-dictionary.js';
|
|
5
4
|
import { PdfObjectReference } from '../../core/objects/pdf-object-reference.js';
|
|
6
5
|
import { PdfArray } from '../../core/objects/pdf-array.js';
|
|
7
6
|
import { PdfString } from '../../core/objects/pdf-string.js';
|
|
7
|
+
import { PdfIndirectObject } from '../../core/index.js';
|
|
8
8
|
/**
|
|
9
9
|
* Choice form field subtype (dropdowns, list boxes).
|
|
10
10
|
*/
|
|
@@ -16,14 +16,16 @@ export class PdfChoiceFormField extends PdfFormField {
|
|
|
16
16
|
return this.options.findIndex((opt) => opt.value === this.value);
|
|
17
17
|
}
|
|
18
18
|
get options() {
|
|
19
|
-
|
|
20
|
-
.get('Opt')
|
|
21
|
-
?.as((PdfArray)) ??
|
|
22
|
-
this.parent?.content
|
|
23
|
-
.get('Opt')
|
|
24
|
-
?.as((PdfArray));
|
|
19
|
+
let opt = this.content.get('Opt') ?? this.parent?.content.get('Opt');
|
|
25
20
|
if (!opt)
|
|
26
21
|
return [];
|
|
22
|
+
if (opt instanceof PdfObjectReference) {
|
|
23
|
+
opt = opt
|
|
24
|
+
.resolve()
|
|
25
|
+
.as((PdfIndirectObject)).content;
|
|
26
|
+
}
|
|
27
|
+
if (!(opt instanceof PdfArray))
|
|
28
|
+
return [];
|
|
27
29
|
return opt.items.map((item) => {
|
|
28
30
|
if (item instanceof PdfArray && item.items.length >= 2) {
|
|
29
31
|
const label = item.items[1] instanceof PdfString
|
|
@@ -47,6 +49,10 @@ export class PdfChoiceFormField extends PdfFormField {
|
|
|
47
49
|
this.content.delete('Opt');
|
|
48
50
|
return;
|
|
49
51
|
}
|
|
52
|
+
if (values instanceof PdfObjectReference) {
|
|
53
|
+
this.content.set('Opt', values);
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
50
56
|
if (values.length === 0) {
|
|
51
57
|
this.content.delete('Opt');
|
|
52
58
|
return;
|
|
@@ -81,36 +87,11 @@ export class PdfChoiceFormField extends PdfFormField {
|
|
|
81
87
|
const parsed = PdfDefaultAppearance.parse(da);
|
|
82
88
|
if (!parsed)
|
|
83
89
|
return false;
|
|
84
|
-
|
|
85
|
-
const
|
|
86
|
-
const
|
|
87
|
-
const
|
|
88
|
-
|
|
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({
|
|
90
|
+
const font = this.font;
|
|
91
|
+
const fontResources = this.buildFontResources(parsed.fontName);
|
|
92
|
+
const isUnicode = font?.isUnicode ?? false;
|
|
93
|
+
const reverseEncodingMap = font?.reverseEncodingMap;
|
|
94
|
+
this.setAppearanceStream(new PdfChoiceAppearanceStream({
|
|
114
95
|
rect: rect,
|
|
115
96
|
value,
|
|
116
97
|
da: parsed,
|
|
@@ -120,7 +101,7 @@ export class PdfChoiceFormField extends PdfFormField {
|
|
|
120
101
|
reverseEncodingMap,
|
|
121
102
|
displayOptions: this.options.map((opt) => opt.label),
|
|
122
103
|
selectedIndex: this.selectedIndex,
|
|
123
|
-
});
|
|
104
|
+
}));
|
|
124
105
|
if (options?.makeReadOnly) {
|
|
125
106
|
this.readOnly = true;
|
|
126
107
|
this.print = true;
|
|
@@ -1,34 +1,43 @@
|
|
|
1
|
+
import { PdfDictionary } from '../../core/objects/pdf-dictionary.js';
|
|
2
|
+
import { PdfArray } from '../../core/objects/pdf-array.js';
|
|
1
3
|
import { PdfString } from '../../core/objects/pdf-string.js';
|
|
2
4
|
import { PdfObjectReference } from '../../core/objects/pdf-object-reference.js';
|
|
3
5
|
import { PdfIndirectObject } from '../../core/objects/pdf-indirect-object.js';
|
|
4
6
|
import { PdfFont } from '../../fonts/pdf-font.js';
|
|
5
7
|
import { PdfStream } from '../../core/objects/pdf-stream.js';
|
|
6
8
|
import { PdfWidgetAnnotation } from '../../annotations/pdf-widget-annotation.js';
|
|
7
|
-
import type {
|
|
8
|
-
import type { FormContext, PdfFieldType } from './types.js';
|
|
9
|
+
import type { PdfFieldType } from './types.js';
|
|
9
10
|
import { PdfFormFieldFlags } from './pdf-form-field-flags.js';
|
|
11
|
+
import { PdfDefaultResourcesDictionary } from '../../annotations/pdf-default-resources.js';
|
|
12
|
+
import type { PdfAcroForm } from '../pdf-acro-form.js';
|
|
10
13
|
/**
|
|
11
14
|
* Abstract base form field class. Extends PdfWidgetAnnotation with form-specific properties:
|
|
12
15
|
* FT, V, DA, Ff, T (name), field hierarchy (parent/children/siblings).
|
|
13
16
|
* Subclasses must implement generateAppearance().
|
|
14
17
|
*/
|
|
15
18
|
export declare abstract class PdfFormField extends PdfWidgetAnnotation {
|
|
16
|
-
private _parent?;
|
|
17
19
|
defaultGenerateAppearance: boolean;
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
other?: PdfIndirectObject;
|
|
23
|
-
form?: FormContext<PdfFormField>;
|
|
24
|
-
parent?: PdfFormField;
|
|
20
|
+
/** @internal */
|
|
21
|
+
_form?: PdfAcroForm;
|
|
22
|
+
constructor(other?: PdfIndirectObject | {
|
|
23
|
+
form?: PdfAcroForm;
|
|
25
24
|
});
|
|
25
|
+
set form(f: PdfAcroForm);
|
|
26
|
+
static create(other?: PdfIndirectObject): PdfFormField;
|
|
26
27
|
get parent(): PdfFormField | undefined;
|
|
27
|
-
set parent(field: PdfFormField | undefined);
|
|
28
|
+
set parent(field: PdfFormField | PdfIndirectObject | undefined);
|
|
28
29
|
get children(): PdfFormField[];
|
|
29
30
|
set children(fields: PdfFormField[]);
|
|
30
31
|
get siblings(): PdfFormField[];
|
|
31
|
-
get
|
|
32
|
+
get font(): PdfFont | null;
|
|
33
|
+
get defaultResources(): PdfDefaultResourcesDictionary | null;
|
|
34
|
+
set defaultResources(resources: PdfDefaultResourcesDictionary | null);
|
|
35
|
+
/**
|
|
36
|
+
* Builds a Resources dictionary containing the font entry for `fontName`,
|
|
37
|
+
* resolved from DR (handling indirect references) or from a loaded font.
|
|
38
|
+
* Returns undefined if neither source provides the font.
|
|
39
|
+
*/
|
|
40
|
+
buildFontResources(fontName: string): PdfDictionary | undefined;
|
|
32
41
|
get fieldType(): PdfFieldType | null;
|
|
33
42
|
set fieldType(type: PdfFieldType | null);
|
|
34
43
|
get name(): string;
|
|
@@ -43,9 +52,6 @@ export declare abstract class PdfFormField extends PdfWidgetAnnotation {
|
|
|
43
52
|
* Override in subclasses to change the stored representation.
|
|
44
53
|
*/
|
|
45
54
|
protected _storeValue(val: string | PdfString, fieldParent: PdfFormField | undefined): boolean;
|
|
46
|
-
protected tryGenerateAppearance(field: PdfFormField): void;
|
|
47
|
-
get checked(): boolean;
|
|
48
|
-
set checked(_isChecked: boolean);
|
|
49
55
|
get fontSize(): number | null;
|
|
50
56
|
set fontSize(size: number);
|
|
51
57
|
get fontName(): string | null;
|
|
@@ -92,32 +98,21 @@ export declare abstract class PdfFormField extends PdfWidgetAnnotation {
|
|
|
92
98
|
set defaultAppearance(da: string);
|
|
93
99
|
get maxLen(): number | null;
|
|
94
100
|
set maxLen(maxLen: number | null);
|
|
95
|
-
get kids(): PdfObjectReference
|
|
101
|
+
get kids(): PdfArray<PdfObjectReference> | undefined;
|
|
96
102
|
set kids(kids: PdfObjectReference[]);
|
|
97
103
|
abstract generateAppearance(options?: {
|
|
98
104
|
makeReadOnly?: boolean;
|
|
99
105
|
textYOffset?: number;
|
|
100
106
|
}): boolean;
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
} | undefined;
|
|
106
|
-
setAppearanceReference(appearanceStreamRef: PdfObjectReference, _appearanceStreamYesRef?: PdfObjectReference): void;
|
|
107
|
+
setAppearanceStream(stream: PdfIndirectObject | {
|
|
108
|
+
[key: string]: PdfIndirectObject;
|
|
109
|
+
}): void;
|
|
110
|
+
getAppearanceStream(setting?: string): PdfIndirectObject<PdfStream> | null;
|
|
107
111
|
private static _fallbackCtor?;
|
|
108
112
|
private static _registry;
|
|
109
|
-
static registerFieldType(ft: 'Sig' | 'Btn' | 'Tx' | 'Ch', ctor: new (options?: {
|
|
110
|
-
other?: PdfIndirectObject;
|
|
111
|
-
form?: FormContext<PdfFormField>;
|
|
112
|
-
parent?: PdfFormField;
|
|
113
|
-
}) => PdfFormField, options?: {
|
|
113
|
+
static registerFieldType(ft: 'Sig' | 'Btn' | 'Tx' | 'Ch', ctor: new (other?: PdfIndirectObject) => PdfFormField, options?: {
|
|
114
114
|
fallback?: boolean;
|
|
115
115
|
}): void;
|
|
116
|
-
static create(options: {
|
|
117
|
-
other: PdfIndirectObject;
|
|
118
|
-
form: FormContext<PdfFormField>;
|
|
119
|
-
parent?: PdfFormField;
|
|
120
|
-
}): PdfFormField;
|
|
121
116
|
}
|
|
122
117
|
/** Backward compatible alias */
|
|
123
118
|
export { PdfFormField as PdfAcroFormField };
|