pdf-lite 1.3.3 → 1.4.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.
Files changed (100) hide show
  1. package/dist/acroform/PdfAcroForm.d.ts +63 -0
  2. package/dist/acroform/PdfAcroForm.js +279 -0
  3. package/dist/acroform/PdfFontEncodingCache.d.ts +16 -0
  4. package/dist/acroform/PdfFontEncodingCache.js +75 -0
  5. package/dist/acroform/acroform.d.ts +7 -454
  6. package/dist/acroform/acroform.js +5 -1664
  7. package/dist/acroform/appearance/PdfAppearanceStream.d.ts +15 -0
  8. package/dist/acroform/appearance/PdfAppearanceStream.js +32 -0
  9. package/dist/acroform/appearance/PdfButtonAppearanceStream.d.ts +12 -0
  10. package/dist/acroform/appearance/PdfButtonAppearanceStream.js +54 -0
  11. package/dist/acroform/appearance/PdfChoiceAppearanceStream.d.ts +15 -0
  12. package/dist/acroform/appearance/PdfChoiceAppearanceStream.js +48 -0
  13. package/dist/acroform/appearance/PdfTextAppearanceStream.d.ts +17 -0
  14. package/dist/acroform/appearance/PdfTextAppearanceStream.js +75 -0
  15. package/dist/acroform/appearance/index.d.ts +4 -0
  16. package/dist/acroform/appearance/index.js +4 -0
  17. package/dist/acroform/fields/PdfButtonFormField.d.ts +9 -0
  18. package/dist/acroform/fields/PdfButtonFormField.js +35 -0
  19. package/dist/acroform/fields/PdfChoiceFormField.d.ts +9 -0
  20. package/dist/acroform/fields/PdfChoiceFormField.js +46 -0
  21. package/dist/acroform/fields/PdfDefaultAppearance.d.ts +23 -0
  22. package/dist/acroform/fields/PdfDefaultAppearance.js +68 -0
  23. package/dist/acroform/fields/PdfFormField.d.ts +119 -0
  24. package/dist/acroform/fields/PdfFormField.js +499 -0
  25. package/dist/acroform/fields/PdfFormFieldFlags.d.ts +46 -0
  26. package/dist/acroform/fields/PdfFormFieldFlags.js +128 -0
  27. package/dist/acroform/fields/PdfSignatureFormField.d.ts +7 -0
  28. package/dist/acroform/fields/PdfSignatureFormField.js +12 -0
  29. package/dist/acroform/fields/PdfTextFormField.d.ts +10 -0
  30. package/dist/acroform/fields/PdfTextFormField.js +52 -0
  31. package/dist/acroform/fields/index.d.ts +8 -0
  32. package/dist/acroform/fields/index.js +8 -0
  33. package/dist/acroform/fields/types.d.ts +21 -0
  34. package/dist/acroform/fields/types.js +9 -0
  35. package/dist/acroform/index.d.ts +5 -1
  36. package/dist/acroform/index.js +5 -1
  37. package/dist/acroform/manager.d.ts +7 -0
  38. package/dist/acroform/manager.js +12 -0
  39. package/dist/acroform/xfa/PdfXfaData.d.ts +20 -0
  40. package/dist/acroform/xfa/PdfXfaData.js +68 -0
  41. package/dist/acroform/xfa/PdfXfaForm.d.ts +12 -0
  42. package/dist/acroform/xfa/PdfXfaForm.js +64 -0
  43. package/dist/acroform/xfa/index.d.ts +3 -0
  44. package/dist/acroform/xfa/index.js +2 -0
  45. package/dist/annotations/PdfAnnotation.d.ts +40 -0
  46. package/dist/annotations/PdfAnnotation.js +105 -0
  47. package/dist/annotations/PdfAnnotationFlags.d.ts +25 -0
  48. package/dist/annotations/PdfAnnotationFlags.js +94 -0
  49. package/dist/annotations/PdfAnnotationWriter.d.ts +20 -0
  50. package/dist/annotations/PdfAnnotationWriter.js +76 -0
  51. package/dist/annotations/PdfWidgetAnnotation.d.ts +15 -0
  52. package/dist/annotations/PdfWidgetAnnotation.js +37 -0
  53. package/dist/annotations/index.d.ts +4 -0
  54. package/dist/annotations/index.js +4 -0
  55. package/dist/core/objects/pdf-array.d.ts +1 -1
  56. package/dist/core/objects/pdf-array.js +3 -2
  57. package/dist/core/objects/pdf-boolean.d.ts +1 -1
  58. package/dist/core/objects/pdf-boolean.js +3 -2
  59. package/dist/core/objects/pdf-comment.d.ts +1 -1
  60. package/dist/core/objects/pdf-comment.js +1 -1
  61. package/dist/core/objects/pdf-dictionary.d.ts +1 -1
  62. package/dist/core/objects/pdf-dictionary.js +3 -2
  63. package/dist/core/objects/pdf-hexadecimal.d.ts +1 -1
  64. package/dist/core/objects/pdf-hexadecimal.js +3 -2
  65. package/dist/core/objects/pdf-indirect-object.d.ts +1 -1
  66. package/dist/core/objects/pdf-indirect-object.js +1 -1
  67. package/dist/core/objects/pdf-name.d.ts +1 -1
  68. package/dist/core/objects/pdf-name.js +3 -2
  69. package/dist/core/objects/pdf-null.d.ts +1 -1
  70. package/dist/core/objects/pdf-null.js +3 -2
  71. package/dist/core/objects/pdf-number.d.ts +1 -1
  72. package/dist/core/objects/pdf-number.js +3 -2
  73. package/dist/core/objects/pdf-object-reference.d.ts +1 -1
  74. package/dist/core/objects/pdf-object-reference.js +3 -2
  75. package/dist/core/objects/pdf-object.d.ts +3 -1
  76. package/dist/core/objects/pdf-object.js +6 -0
  77. package/dist/core/objects/pdf-start-xref.d.ts +1 -1
  78. package/dist/core/objects/pdf-start-xref.js +3 -2
  79. package/dist/core/objects/pdf-stream.d.ts +3 -3
  80. package/dist/core/objects/pdf-stream.js +39 -14
  81. package/dist/core/objects/pdf-string.d.ts +2 -1
  82. package/dist/core/objects/pdf-string.js +17 -2
  83. package/dist/core/objects/pdf-trailer.d.ts +1 -1
  84. package/dist/core/objects/pdf-trailer.js +3 -2
  85. package/dist/core/objects/pdf-xref-table.d.ts +3 -3
  86. package/dist/core/objects/pdf-xref-table.js +3 -3
  87. package/dist/index.d.ts +1 -0
  88. package/dist/index.js +1 -0
  89. package/dist/pdf/pdf-document.d.ts +14 -11
  90. package/dist/pdf/pdf-document.js +36 -26
  91. package/dist/pdf/pdf-revision.d.ts +1 -1
  92. package/dist/pdf/pdf-revision.js +1 -1
  93. package/dist/pdf/pdf-xref-lookup.d.ts +8 -0
  94. package/dist/pdf/pdf-xref-lookup.js +12 -0
  95. package/dist/security/handlers/base.js +3 -0
  96. package/package.json +1 -1
  97. package/dist/xfa/index.d.ts +0 -1
  98. package/dist/xfa/index.js +0 -1
  99. package/dist/xfa/manager.d.ts +0 -44
  100. package/dist/xfa/manager.js +0 -136
@@ -0,0 +1,76 @@
1
+ import { PdfDictionary } from '../core/objects/pdf-dictionary.js';
2
+ import { PdfArray } from '../core/objects/pdf-array.js';
3
+ import { PdfObjectReference } from '../core/objects/pdf-object-reference.js';
4
+ import { PdfIndirectObject } from '../core/objects/pdf-indirect-object.js';
5
+ /**
6
+ * Manages page Annots arrays during AcroForm write operations.
7
+ */
8
+ export class PdfAnnotationWriter {
9
+ static async getPageAnnotsArray(document, pageDict) {
10
+ const annotsRef = pageDict.get('Annots');
11
+ if (annotsRef instanceof PdfObjectReference) {
12
+ const annotsObj = await document.readObject({
13
+ objectNumber: annotsRef.objectNumber,
14
+ generationNumber: annotsRef.generationNumber,
15
+ });
16
+ return {
17
+ annotsArray: annotsObj.content
18
+ .as((PdfArray))
19
+ .clone(),
20
+ isIndirect: true,
21
+ objectNumber: annotsRef.objectNumber,
22
+ generationNumber: annotsRef.generationNumber,
23
+ };
24
+ }
25
+ else if (annotsRef instanceof PdfArray) {
26
+ return {
27
+ annotsArray: annotsRef.as((PdfArray)).clone(),
28
+ isIndirect: false,
29
+ };
30
+ }
31
+ else {
32
+ const newArray = new PdfArray();
33
+ pageDict.set('Annots', newArray);
34
+ return {
35
+ annotsArray: newArray,
36
+ isIndirect: false,
37
+ };
38
+ }
39
+ }
40
+ static addFieldsToAnnots(annotsArray, fieldRefs) {
41
+ for (const fieldRef of fieldRefs) {
42
+ const exists = annotsArray.items.some((ref) => ref.equals(fieldRef));
43
+ if (!exists) {
44
+ annotsArray.push(fieldRef);
45
+ }
46
+ }
47
+ }
48
+ static async updatePageAnnotations(document, fieldsByPage) {
49
+ for (const { pageRef, fieldRefs } of fieldsByPage.values()) {
50
+ const pageObj = await document.readObject({
51
+ objectNumber: pageRef.objectNumber,
52
+ generationNumber: pageRef.generationNumber,
53
+ });
54
+ if (!pageObj)
55
+ continue;
56
+ const pageDict = pageObj.content.as(PdfDictionary).clone();
57
+ const annotsInfo = await PdfAnnotationWriter.getPageAnnotsArray(document, pageDict);
58
+ PdfAnnotationWriter.addFieldsToAnnots(annotsInfo.annotsArray, fieldRefs);
59
+ if (annotsInfo.isIndirect &&
60
+ annotsInfo.objectNumber !== undefined) {
61
+ const annotsIndirect = new PdfIndirectObject({
62
+ objectNumber: annotsInfo.objectNumber,
63
+ generationNumber: annotsInfo.generationNumber,
64
+ content: annotsInfo.annotsArray,
65
+ });
66
+ document.add(annotsIndirect);
67
+ }
68
+ const pageIndirect = new PdfIndirectObject({
69
+ objectNumber: pageRef.objectNumber,
70
+ generationNumber: pageRef.generationNumber,
71
+ content: pageDict,
72
+ });
73
+ document.add(pageIndirect);
74
+ }
75
+ }
76
+ }
@@ -0,0 +1,15 @@
1
+ import { PdfIndirectObject } from '../core/objects/pdf-indirect-object.js';
2
+ import { PdfAnnotation } from './PdfAnnotation.js';
3
+ /**
4
+ * Widget annotation subtype. Extends PdfAnnotation with widget-specific
5
+ * properties: isWidget (Type/Subtype) and AS (appearance state).
6
+ */
7
+ export declare class PdfWidgetAnnotation extends PdfAnnotation {
8
+ constructor(options?: {
9
+ other?: PdfIndirectObject;
10
+ });
11
+ get isWidget(): boolean;
12
+ set isWidget(isWidget: boolean);
13
+ get appearanceState(): string | null;
14
+ set appearanceState(state: string | null);
15
+ }
@@ -0,0 +1,37 @@
1
+ import { PdfName } from '../core/objects/pdf-name.js';
2
+ import { PdfAnnotation } from './PdfAnnotation.js';
3
+ /**
4
+ * Widget annotation subtype. Extends PdfAnnotation with widget-specific
5
+ * properties: isWidget (Type/Subtype) and AS (appearance state).
6
+ */
7
+ export class PdfWidgetAnnotation extends PdfAnnotation {
8
+ constructor(options) {
9
+ super(options);
10
+ }
11
+ get isWidget() {
12
+ const type = this.content.get('Type')?.as(PdfName)?.value;
13
+ const subtype = this.content.get('Subtype')?.as(PdfName)?.value;
14
+ return type === 'Annot' && subtype === 'Widget';
15
+ }
16
+ set isWidget(isWidget) {
17
+ if (isWidget) {
18
+ this.content.set('Type', new PdfName('Annot'));
19
+ this.content.set('Subtype', new PdfName('Widget'));
20
+ }
21
+ else {
22
+ this.content.delete('Type');
23
+ this.content.delete('Subtype');
24
+ }
25
+ }
26
+ get appearanceState() {
27
+ return this.content.get('AS')?.as(PdfName)?.value ?? null;
28
+ }
29
+ set appearanceState(state) {
30
+ if (state === null) {
31
+ this.content.delete('AS');
32
+ }
33
+ else {
34
+ this.content.set('AS', new PdfName(state));
35
+ }
36
+ }
37
+ }
@@ -0,0 +1,4 @@
1
+ export { PdfAnnotation, type PdfAppearanceStreamDictionary, } from './PdfAnnotation.js';
2
+ export { PdfAnnotationFlags } from './PdfAnnotationFlags.js';
3
+ export { PdfWidgetAnnotation } from './PdfWidgetAnnotation.js';
4
+ export { PdfAnnotationWriter } from './PdfAnnotationWriter.js';
@@ -0,0 +1,4 @@
1
+ export { PdfAnnotation, } from './PdfAnnotation.js';
2
+ export { PdfAnnotationFlags } from './PdfAnnotationFlags.js';
3
+ export { PdfWidgetAnnotation } from './PdfWidgetAnnotation.js';
4
+ export { PdfAnnotationWriter } from './PdfAnnotationWriter.js';
@@ -7,7 +7,7 @@ export declare class PdfArray<T extends PdfObject = PdfObject> extends PdfObject
7
7
  get length(): number;
8
8
  push(item: T): void;
9
9
  protected tokenize(): import("../index.js").PdfToken[];
10
- clone(): this;
10
+ cloneImpl(): this;
11
11
  isModified(): boolean;
12
12
  setImmutable(immutable?: boolean): void;
13
13
  }
@@ -33,8 +33,9 @@ export class PdfArray extends PdfObject {
33
33
  new PdfEndArrayToken(),
34
34
  ];
35
35
  }
36
- clone() {
37
- return new PdfArray(this.items.map((x) => x.clone()));
36
+ cloneImpl() {
37
+ const cloned = new PdfArray(this.items.map((x) => x.clone()));
38
+ return cloned;
38
39
  }
39
40
  isModified() {
40
41
  return (super.isModified() || this.items.some((item) => item.isModified()));
@@ -4,5 +4,5 @@ export declare class PdfBoolean extends PdfObject {
4
4
  value: boolean;
5
5
  constructor(value: boolean);
6
6
  protected tokenize(): PdfBooleanToken[];
7
- clone(): this;
7
+ cloneImpl(): this;
8
8
  }
@@ -9,7 +9,8 @@ export class PdfBoolean extends PdfObject {
9
9
  tokenize() {
10
10
  return [new PdfBooleanToken(this.value)];
11
11
  }
12
- clone() {
13
- return new PdfBoolean(this.value);
12
+ cloneImpl() {
13
+ const cloned = new PdfBoolean(this.value);
14
+ return cloned;
14
15
  }
15
16
  }
@@ -14,5 +14,5 @@ export declare class PdfComment extends PdfObject {
14
14
  isEOFComment(): boolean;
15
15
  static versionComment(version: string): PdfComment;
16
16
  protected tokenize(): PdfCommentToken[];
17
- clone(): this;
17
+ cloneImpl(): this;
18
18
  }
@@ -33,7 +33,7 @@ export class PdfComment extends PdfObject {
33
33
  tokenize() {
34
34
  return [new PdfCommentToken(this.raw)];
35
35
  }
36
- clone() {
36
+ cloneImpl() {
37
37
  return new PdfComment(new Uint8Array(this.raw));
38
38
  }
39
39
  }
@@ -22,7 +22,7 @@ export declare class PdfDictionary<T extends PdfDictionaryEntries = PdfDictionar
22
22
  entries(): IterableIterator<[string, PdfObject | undefined]>;
23
23
  protected tokenize(): PdfToken[];
24
24
  copyFrom(other: PdfDictionary<any>): void;
25
- clone(): this;
25
+ cloneImpl(): this;
26
26
  isModified(): boolean;
27
27
  setImmutable(immutable?: boolean): void;
28
28
  }
@@ -136,12 +136,13 @@ export class PdfDictionary extends PdfObject {
136
136
  }
137
137
  this.modified = true;
138
138
  }
139
- clone() {
139
+ cloneImpl() {
140
140
  const clonedEntries = new Map();
141
141
  for (const [key, value] of this.#entries) {
142
142
  clonedEntries.set(key.clone(), value ? value.clone() : undefined);
143
143
  }
144
- return new PdfDictionary(clonedEntries);
144
+ const cloned = new PdfDictionary(clonedEntries);
145
+ return cloned;
145
146
  }
146
147
  isModified() {
147
148
  return (super.isModified() ||
@@ -20,5 +20,5 @@ export declare class PdfHexadecimal extends PdfObject {
20
20
  toHexBytes(): ByteArray;
21
21
  toHexString(): string;
22
22
  protected tokenize(): PdfHexadecimalToken[];
23
- clone(): this;
23
+ cloneImpl(): this;
24
24
  }
@@ -54,9 +54,10 @@ export class PdfHexadecimal extends PdfObject {
54
54
  tokenize() {
55
55
  return [new PdfHexadecimalToken(this.raw, this._originalBytes)];
56
56
  }
57
- clone() {
58
- return new PdfHexadecimal(new Uint8Array(this.raw), 'hex', this._originalBytes
57
+ cloneImpl() {
58
+ const cloned = new PdfHexadecimal(new Uint8Array(this.raw), 'hex', this._originalBytes
59
59
  ? new Uint8Array(this._originalBytes)
60
60
  : undefined);
61
+ return cloned;
61
62
  }
62
63
  }
@@ -22,7 +22,7 @@ export declare class PdfIndirectObject<T extends PdfObject = PdfObject> extends
22
22
  matchesReference(ref?: PdfObjectReference): boolean;
23
23
  protected tokenize(): import("../index.js").PdfToken[];
24
24
  copyFrom(other: PdfIndirectObject): void;
25
- clone(): this;
25
+ cloneImpl(): this;
26
26
  order(): number;
27
27
  isModified(): boolean;
28
28
  setImmutable(immutable?: boolean): void;
@@ -94,7 +94,7 @@ export class PdfIndirectObject extends PdfObjectReference {
94
94
  this.offset = other.offset.clone();
95
95
  this.modified = true;
96
96
  }
97
- clone() {
97
+ cloneImpl() {
98
98
  return new PdfIndirectObject({
99
99
  objectNumber: this.objectNumber,
100
100
  generationNumber: this.generationNumber,
@@ -4,7 +4,7 @@ export declare class PdfName<T extends string = string> extends PdfObject {
4
4
  value: T;
5
5
  constructor(value: T);
6
6
  protected tokenize(): PdfNameToken[];
7
- clone(): this;
7
+ cloneImpl(): this;
8
8
  /**
9
9
  * Escapes a PDF name according to PDF specification.
10
10
  * PDF names can't contain spaces or certain special chars except # for escaping.
@@ -9,8 +9,9 @@ export class PdfName extends PdfObject {
9
9
  tokenize() {
10
10
  return [new PdfNameToken(PdfName.escapeName(this.value))];
11
11
  }
12
- clone() {
13
- return new PdfName(this.value);
12
+ cloneImpl() {
13
+ const cloned = new PdfName(this.value);
14
+ return cloned;
14
15
  }
15
16
  /**
16
17
  * Escapes a PDF name according to PDF specification.
@@ -3,5 +3,5 @@ import { PdfNullToken } from '../tokens/null-token.js';
3
3
  export declare class PdfNull extends PdfObject {
4
4
  static readonly NULL: PdfNull;
5
5
  protected tokenize(): PdfNullToken[];
6
- clone(): this;
6
+ cloneImpl(): this;
7
7
  }
@@ -5,7 +5,8 @@ export class PdfNull extends PdfObject {
5
5
  tokenize() {
6
6
  return [new PdfNullToken()];
7
7
  }
8
- clone() {
9
- return new PdfNull();
8
+ cloneImpl() {
9
+ const cloned = new PdfNull();
10
+ return cloned;
10
11
  }
11
12
  }
@@ -17,7 +17,7 @@ export declare class PdfNumber extends PdfObject {
17
17
  onChange(callback: (value: number) => void): void;
18
18
  toToken(): PdfNumberToken;
19
19
  protected tokenize(): PdfNumberToken[];
20
- clone(): this;
20
+ cloneImpl(): this;
21
21
  isModified(): boolean;
22
22
  }
23
23
  export declare class PdfByteOffsetNumber extends PdfNumber {
@@ -64,12 +64,13 @@ export class PdfNumber extends PdfObject {
64
64
  tokenize() {
65
65
  return [this.toToken()];
66
66
  }
67
- clone() {
68
- return new PdfNumber({
67
+ cloneImpl() {
68
+ const cloned = new PdfNumber({
69
69
  value: this.value,
70
70
  padTo: this.padTo,
71
71
  decimalPlaces: this.decimalPlaces,
72
72
  });
73
+ return cloned;
73
74
  }
74
75
  isModified() {
75
76
  return super.isModified() || this.#value.isModified;
@@ -5,5 +5,5 @@ export declare class PdfObjectReference extends PdfObject {
5
5
  generationNumber: number;
6
6
  constructor(objectNumber: number, generationNumber: number);
7
7
  protected tokenize(): PdfToken[];
8
- clone(): this;
8
+ cloneImpl(): this;
9
9
  }
@@ -13,7 +13,8 @@ export class PdfObjectReference extends PdfObject {
13
13
  new PdfObjectReferenceToken(this.objectNumber, this.generationNumber),
14
14
  ];
15
15
  }
16
- clone() {
17
- return new PdfObjectReference(this.objectNumber, this.generationNumber);
16
+ cloneImpl() {
17
+ const cloned = new PdfObjectReference(this.objectNumber, this.generationNumber);
18
+ return cloned;
18
19
  }
19
20
  }
@@ -29,8 +29,10 @@ export declare abstract class PdfObject {
29
29
  toString(): string;
30
30
  /** Attempts to cast the object to a specific PdfObject subclass */
31
31
  as<T extends PdfObject>(ctor: new (...args: any[]) => T): T;
32
+ /** Creates a deep clone of the object. Override this method in subclasses to ensure all properties are cloned correctly */
33
+ protected abstract cloneImpl(): this;
32
34
  /** Creates a deep clone of the object */
33
- abstract clone(): this;
35
+ clone(): this;
34
36
  /** Compares this object to another for equality based on their token representations */
35
37
  equals(other?: PdfObject): boolean;
36
38
  }
@@ -63,6 +63,12 @@ export class PdfObject {
63
63
  }
64
64
  throw new Error(`Cannot cast object of type ${this.objectType} to ${ctor.name}`);
65
65
  }
66
+ /** Creates a deep clone of the object */
67
+ clone() {
68
+ const cloned = this.cloneImpl();
69
+ cloned.setModified(this.modified);
70
+ return cloned;
71
+ }
66
72
  /** Compares this object to another for equality based on their token representations */
67
73
  equals(other) {
68
74
  if (!other) {
@@ -5,6 +5,6 @@ export declare class PdfStartXRef extends PdfObject {
5
5
  offset: PdfNumber;
6
6
  constructor(offset?: number | PdfNumber | Ref<number>);
7
7
  protected tokenize(): import("../index.js").PdfToken[];
8
- clone(): this;
8
+ cloneImpl(): this;
9
9
  isModified(): boolean;
10
10
  }
@@ -23,8 +23,9 @@ export class PdfStartXRef extends PdfObject {
23
23
  ...this.offset.toTokens(),
24
24
  ];
25
25
  }
26
- clone() {
27
- return new PdfStartXRef(this.offset.clone());
26
+ cloneImpl() {
27
+ const cloned = new PdfStartXRef(this.offset.clone());
28
+ return cloned;
28
29
  }
29
30
  isModified() {
30
31
  return super.isModified() || this.offset.isModified();
@@ -53,7 +53,7 @@ export declare class PdfStream<T extends PdfDictionary = PdfDictionary> extends
53
53
  readonly Crypt: PdfFilter;
54
54
  };
55
55
  static applyFilters(data: ByteArray, filters: PdfStreamFilterType[]): ByteArray;
56
- clone(): this;
56
+ cloneImpl(): this;
57
57
  static fromString(data: string): PdfStream;
58
58
  }
59
59
  export declare class PdfObjStream extends PdfStream {
@@ -68,7 +68,7 @@ export declare class PdfObjStream extends PdfStream {
68
68
  objectNumber: number;
69
69
  }): PdfIndirectObject | undefined;
70
70
  getObjects(): PdfIndirectObject[];
71
- clone(): this;
71
+ cloneImpl(): this;
72
72
  }
73
73
  export declare class PdfXRefStreamCompressedEntry {
74
74
  objectNumber: PdfNumber;
@@ -97,5 +97,5 @@ export declare class PdfXRefStream extends PdfStream {
97
97
  getEntryStream(): Generator<PdfXRefStreamEntry>;
98
98
  getEntries(): PdfXRefStreamEntry[];
99
99
  private readInt;
100
- clone(): this;
100
+ cloneImpl(): this;
101
101
  }
@@ -217,7 +217,7 @@ export class PdfStream extends PdfObject {
217
217
  }
218
218
  return result;
219
219
  }
220
- clone() {
220
+ cloneImpl() {
221
221
  return new PdfStream({
222
222
  header: this.header.clone(),
223
223
  original: new Uint8Array(this.original),
@@ -238,23 +238,48 @@ export class PdfObjStream extends PdfStream {
238
238
  }
239
239
  }
240
240
  static fromObjects(objects) {
241
- let header = '';
242
- let objectData = '';
241
+ const objByteChunks = [];
242
+ const headerParts = [];
243
243
  let offset = 0;
244
+ let objectCount = 0;
244
245
  for (const obj of objects) {
245
- header += `${obj.objectNumber} ${offset} `;
246
- const objString = obj.content.toString();
247
- objectData += objString + '\n';
248
- offset += objString.length + 1;
249
- }
246
+ // Use toBytes() to preserve binary content (e.g. UTF-16BE strings)
247
+ // instead of toString() which is Latin-1 and would be re-encoded as UTF-8
248
+ headerParts.push(`${obj.objectNumber} ${offset}`);
249
+ const bytes = obj.content.toBytes();
250
+ objByteChunks.push(bytes, new Uint8Array([0x0a])); // object + newline
251
+ offset += bytes.length + 1;
252
+ objectCount++;
253
+ }
254
+ const headerStr = headerParts.join(' ');
255
+ // First = byte offset of first compressed object from stream start
256
+ const first = objectCount > 0 ? headerStr.length + 1 : 0;
250
257
  const headerDict = new PdfDictionary();
251
258
  headerDict.set('Type', new PdfName('ObjStm'));
252
- headerDict.set('N', new PdfNumber(header.length));
253
- headerDict.set('First', new PdfNumber(offset));
254
- objectData = `${header.trim()}\n${objectData.trim()}`;
259
+ headerDict.set('N', new PdfNumber(objectCount));
260
+ headerDict.set('First', new PdfNumber(first));
261
+ if (objectCount === 0) {
262
+ return new PdfObjStream({
263
+ header: headerDict,
264
+ original: new Uint8Array(),
265
+ });
266
+ }
267
+ // Build stream bytes: headerStr + '\n' + obj1bytes + obj2bytes + ...
268
+ // Drop trailing newline after the last object
269
+ objByteChunks.pop();
270
+ const headerBytes = stringToBytes(headerStr + '\n');
271
+ const totalLength = objByteChunks.reduce((sum, chunk) => sum + chunk.length, headerBytes.length);
272
+ const streamBytes = new Uint8Array(totalLength);
273
+ let pos = 0;
274
+ streamBytes.set(headerBytes, pos);
275
+ pos += headerBytes.length;
276
+ for (const chunk of objByteChunks) {
277
+ streamBytes.set(chunk, pos);
278
+ pos += chunk.length;
279
+ }
255
280
  return new PdfObjStream({
256
281
  header: headerDict,
257
- original: objectData,
282
+ original: streamBytes,
258
283
  });
259
284
  }
260
285
  *getObjectStream() {
@@ -302,7 +327,7 @@ export class PdfObjStream extends PdfStream {
302
327
  getObjects() {
303
328
  return Array.from(this.getObjectStream());
304
329
  }
305
- clone() {
330
+ cloneImpl() {
306
331
  return new PdfObjStream({
307
332
  header: this.header.clone(),
308
333
  original: new Uint8Array(this.original),
@@ -528,7 +553,7 @@ export class PdfXRefStream extends PdfStream {
528
553
  }
529
554
  return value;
530
555
  }
531
- clone() {
556
+ cloneImpl() {
532
557
  return new PdfXRefStream({
533
558
  header: this.header.clone(),
534
559
  original: new Uint8Array(this.original),
@@ -19,7 +19,8 @@ export declare class PdfString extends PdfObject {
19
19
  * UTF-16BE strings start with the byte order mark 0xFE 0xFF.
20
20
  */
21
21
  get isUTF16BE(): boolean;
22
+ set value(str: string);
22
23
  get value(): string;
23
24
  protected tokenize(): PdfStringToken[];
24
- clone(): this;
25
+ cloneImpl(): this;
25
26
  }
@@ -52,6 +52,20 @@ export class PdfString extends PdfObject {
52
52
  get isUTF16BE() {
53
53
  return (this.raw.length >= 2 && this.raw[0] === 0xfe && this.raw[1] === 0xff);
54
54
  }
55
+ set value(str) {
56
+ if (this.isImmutable()) {
57
+ throw new Error('Cannot modify an immutable PdfString');
58
+ }
59
+ this.setModified();
60
+ if (needsUnicodeEncoding(str)) {
61
+ this._raw = encodeAsUTF16BE(str);
62
+ }
63
+ else {
64
+ this._raw = encodeToPDFDocEncoding(str);
65
+ }
66
+ // Clear original bytes when modified
67
+ this._originalBytes = undefined;
68
+ }
55
69
  get value() {
56
70
  // Check for UTF-16BE BOM (0xFE 0xFF)
57
71
  if (this.isUTF16BE) {
@@ -63,9 +77,10 @@ export class PdfString extends PdfObject {
63
77
  tokenize() {
64
78
  return [new PdfStringToken(this.raw, this._originalBytes)];
65
79
  }
66
- clone() {
67
- return new PdfString(new Uint8Array(this.raw), this._originalBytes
80
+ cloneImpl() {
81
+ const cloned = new PdfString(new Uint8Array(this.raw), this._originalBytes
68
82
  ? new Uint8Array(this._originalBytes)
69
83
  : undefined);
84
+ return cloned;
70
85
  }
71
86
  }
@@ -21,6 +21,6 @@ export declare class PdfTrailer extends PdfObject {
21
21
  offset: Ref<number>;
22
22
  constructor(entries: PdfTrailerEntries | PdfDictionary<PdfTrailerEntries>);
23
23
  protected tokenize(): PdfToken[];
24
- clone(): this;
24
+ cloneImpl(): this;
25
25
  isModified(): boolean;
26
26
  }
@@ -22,8 +22,9 @@ export class PdfTrailer extends PdfObject {
22
22
  ...this.dict.toTokens(),
23
23
  ];
24
24
  }
25
- clone() {
26
- return new PdfTrailer(this.dict.clone());
25
+ cloneImpl() {
26
+ const cloned = new PdfTrailer(this.dict.clone());
27
+ return cloned;
27
28
  }
28
29
  isModified() {
29
30
  return (super.isModified() ||
@@ -16,7 +16,7 @@ export declare class PdfXRefTableEntry extends PdfObject {
16
16
  inUse: boolean;
17
17
  });
18
18
  protected tokenize(): PdfXRefTableEntryToken[];
19
- clone(): this;
19
+ cloneImpl(): this;
20
20
  isModified(): boolean;
21
21
  }
22
22
  export declare class PdfXRefTableSectionHeader extends PdfObject {
@@ -27,7 +27,7 @@ export declare class PdfXRefTableSectionHeader extends PdfObject {
27
27
  entryCount: number | PdfNumber;
28
28
  });
29
29
  protected tokenize(): PdfXRefTableSectionStartToken[];
30
- clone(): this;
30
+ cloneImpl(): this;
31
31
  }
32
32
  export declare class PdfXRefTable extends PdfObject {
33
33
  sections: PdfXRefTableSectionHeader[];
@@ -44,5 +44,5 @@ export declare class PdfXRefTable extends PdfObject {
44
44
  get lastSection(): PdfXRefTableSectionHeader | null;
45
45
  protected tokenize(): import("../index.js").PdfToken[];
46
46
  private sortEntriesIntoSections;
47
- clone(): this;
47
+ cloneImpl(): this;
48
48
  }
@@ -36,7 +36,7 @@ export class PdfXRefTableEntry extends PdfObject {
36
36
  new PdfXRefTableEntryToken(this.byteOffset.toToken(), this.generationNumber.toToken(), this.objectNumber.toToken(), this.inUse),
37
37
  ];
38
38
  }
39
- clone() {
39
+ cloneImpl() {
40
40
  return new PdfXRefTableEntry({
41
41
  byteOffset: this.byteOffset.clone(),
42
42
  objectNumber: this.objectNumber.clone(),
@@ -64,7 +64,7 @@ export class PdfXRefTableSectionHeader extends PdfObject {
64
64
  new PdfXRefTableSectionStartToken(this.startObjectNumber.value, this.entryCount.value),
65
65
  ];
66
66
  }
67
- clone() {
67
+ cloneImpl() {
68
68
  return new PdfXRefTableSectionHeader({
69
69
  startObjectNumber: this.startObjectNumber.clone(),
70
70
  entryCount: this.entryCount.clone(),
@@ -173,7 +173,7 @@ export class PdfXRefTable extends PdfObject {
173
173
  }
174
174
  return sections;
175
175
  }
176
- clone() {
176
+ cloneImpl() {
177
177
  return new PdfXRefTable({
178
178
  sections: this.sections.map((s) => s.clone()),
179
179
  entries: this.entries.map((e) => e.clone()),
package/dist/index.d.ts CHANGED
@@ -7,3 +7,4 @@ export * from './pdf/index.js';
7
7
  export * from './security/index.js';
8
8
  export * from './signing/index.js';
9
9
  export * from './utils/index.js';
10
+ export * from './annotations/index.js';