@adnsistemas/pdf-lib 2.7.2 → 2.7.3

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 (47) hide show
  1. package/README.md +4 -3
  2. package/cjs/api/PDFDocument.js +1 -1
  3. package/cjs/api/PDFDocument.js.map +1 -1
  4. package/cjs/api/snapshot/IncrementalDocumentSnapshot.d.ts +1 -1
  5. package/cjs/api/snapshot/IncrementalDocumentSnapshot.d.ts.map +1 -1
  6. package/cjs/api/snapshot/IncrementalDocumentSnapshot.js +3 -7
  7. package/cjs/api/snapshot/IncrementalDocumentSnapshot.js.map +1 -1
  8. package/cjs/core/objects/PDFString.js +1 -1
  9. package/cjs/core/parser/PDFObjectParser.d.ts.map +1 -1
  10. package/cjs/core/parser/PDFObjectParser.js +2 -1
  11. package/cjs/core/parser/PDFObjectParser.js.map +1 -1
  12. package/cjs/core/writers/PDFWriter.d.ts +8 -3
  13. package/cjs/core/writers/PDFWriter.d.ts.map +1 -1
  14. package/cjs/core/writers/PDFWriter.js +30 -7
  15. package/cjs/core/writers/PDFWriter.js.map +1 -1
  16. package/dist/pdf-lib.esm.js +37 -17
  17. package/dist/pdf-lib.esm.js.map +1 -1
  18. package/dist/pdf-lib.esm.min.js +3 -3
  19. package/dist/pdf-lib.esm.min.js.map +1 -1
  20. package/dist/pdf-lib.js +37 -17
  21. package/dist/pdf-lib.js.map +1 -1
  22. package/dist/pdf-lib.min.js +3 -3
  23. package/dist/pdf-lib.min.js.map +1 -1
  24. package/es/api/PDFDocument.js +1 -1
  25. package/es/api/PDFDocument.js.map +1 -1
  26. package/es/api/snapshot/IncrementalDocumentSnapshot.d.ts +1 -1
  27. package/es/api/snapshot/IncrementalDocumentSnapshot.d.ts.map +1 -1
  28. package/es/api/snapshot/IncrementalDocumentSnapshot.js +3 -7
  29. package/es/api/snapshot/IncrementalDocumentSnapshot.js.map +1 -1
  30. package/es/core/objects/PDFString.js +1 -1
  31. package/es/core/parser/PDFObjectParser.d.ts.map +1 -1
  32. package/es/core/parser/PDFObjectParser.js +3 -2
  33. package/es/core/parser/PDFObjectParser.js.map +1 -1
  34. package/es/core/writers/PDFWriter.d.ts +8 -3
  35. package/es/core/writers/PDFWriter.d.ts.map +1 -1
  36. package/es/core/writers/PDFWriter.js +30 -7
  37. package/es/core/writers/PDFWriter.js.map +1 -1
  38. package/package.json +1 -1
  39. package/src/api/PDFDocument.ts +1 -1
  40. package/src/api/snapshot/IncrementalDocumentSnapshot.ts +5 -11
  41. package/src/core/objects/PDFString.ts +1 -1
  42. package/src/core/parser/PDFObjectParser.ts +5 -2
  43. package/src/core/writers/PDFWriter.ts +32 -9
  44. package/ts3.4/cjs/api/snapshot/IncrementalDocumentSnapshot.d.ts +1 -1
  45. package/ts3.4/cjs/core/writers/PDFWriter.d.ts +11 -3
  46. package/ts3.4/es/api/snapshot/IncrementalDocumentSnapshot.d.ts +1 -1
  47. package/ts3.4/es/core/writers/PDFWriter.d.ts +11 -3
@@ -62,27 +62,48 @@ class PDFWriter {
62
62
  */
63
63
  protected _largestSkippedObjectNum: number = 0;
64
64
 
65
+ /**
66
+ * Used to check wheter an object should be saved or not, preserves the object number of the
67
+ * last XRef Stream object, if there is one.
68
+ */
69
+ protected _lastXRefObjectNumber: number = 0;
65
70
  /**
66
71
  * For incremental saves, defers the decision to the snapshot.
67
- * For full saves, checks that the object is not an XRef stream object.
72
+ * For full saves, checks that the object is not the last XRef stream object.
68
73
  * @param {boolean} incremental If making an incremental save, or a full save of the PDF
69
74
  * @param {number} objNum Object number
70
- * @param {PDFObject} object PDFObject used to check if it is an XRef stream, when not 'incremental' saving
75
+ * @param {[PDFRef, PDFObject][]} objects List of objects that form the PDF
71
76
  * @returns {boolean} whether the object should be saved or not
72
77
  */
73
78
  protected shouldSave(
74
79
  incremental: boolean,
75
80
  objNum: number,
76
- object: PDFObject,
81
+ objects: [PDFRef, PDFObject][],
77
82
  ): boolean {
78
83
  let should = true;
79
84
  if (incremental) {
80
85
  should = this.snapshot.shouldSave(objNum);
81
86
  } else {
82
- should = !(
83
- object instanceof PDFRawStream &&
84
- object.dict.lookup(PDFName.of('Type')) === PDFName.of('XRef')
85
- );
87
+ // only the last XRef Stream will be regenerated on save
88
+ if (!this._lastXRefObjectNumber) {
89
+ // if no XRef Stream, then nothing should be skipped
90
+ this._lastXRefObjectNumber = this.context.largestObjectNumber + 1;
91
+ const checkWatermark = this._lastXRefObjectNumber - 10; // max number of objects in the final part of the PDF to check
92
+ // search the last XRef Stream, if there is one, objects are expected to be in object number order
93
+ for (let idx = objects.length - 1; idx > 0; idx--) {
94
+ // if not in last 'rangeToCheck' objects, there is none that should be skipped, most probably a linearized PDF, or without XRef Streams
95
+ if (objects[idx][0].objectNumber < checkWatermark) break;
96
+ const object = objects[idx][1];
97
+ if (
98
+ object instanceof PDFRawStream &&
99
+ object.dict.lookup(PDFName.of('Type')) === PDFName.of('XRef')
100
+ ) {
101
+ this._lastXRefObjectNumber = objects[idx][0].objectNumber;
102
+ break;
103
+ }
104
+ }
105
+ }
106
+ should = objNum !== this._lastXRefObjectNumber;
86
107
  }
87
108
  if (!should && this._largestSkippedObjectNum < objNum)
88
109
  this._largestSkippedObjectNum = objNum;
@@ -106,7 +127,7 @@ class PDFWriter {
106
127
  for (let idx = 0, len = indirectObjects.length; idx < len; idx++) {
107
128
  const [ref, object] = indirectObjects[idx];
108
129
 
109
- if (!this.shouldSave(incremental, ref.objectNumber, object)) {
130
+ if (!this.shouldSave(incremental, ref.objectNumber, indirectObjects)) {
110
131
  continue;
111
132
  }
112
133
 
@@ -189,6 +210,7 @@ class PDFWriter {
189
210
  incremental: boolean,
190
211
  ): Promise<SerializationInfo> {
191
212
  this._largestSkippedObjectNum = 0;
213
+ this._lastXRefObjectNumber = 0;
192
214
  const header = PDFHeader.forVersion(1, 7);
193
215
 
194
216
  let size = this.snapshot.pdfSize;
@@ -206,7 +228,8 @@ class PDFWriter {
206
228
  for (let idx = 0, len = indirectObjects.length; idx < len; idx++) {
207
229
  const indirectObject = indirectObjects[idx];
208
230
  const [ref, object] = indirectObject;
209
- if (!this.shouldSave(incremental, ref.objectNumber, object)) continue;
231
+ if (!this.shouldSave(incremental, ref.objectNumber, indirectObjects))
232
+ continue;
210
233
  if (security) this.encrypt(ref, object, security);
211
234
  xref.addEntry(ref, size);
212
235
  size += this.computeIndirectObjectSize(indirectObject);
@@ -8,7 +8,7 @@ export declare class IncrementalDocumentSnapshot implements DocumentSnapshot {
8
8
  private lastObjectNumber;
9
9
  private changedObjects;
10
10
  context: PDFContext;
11
- constructor(lastObjectNumber: number, indirectObjects: number[], pdfSize: number, prevStartXRef: number, context: PDFContext);
11
+ constructor(lastObjectNumber: number, indirectObjects: Set<number>, pdfSize: number, prevStartXRef: number, context: PDFContext);
12
12
  shouldSave(objectNumber: number): boolean;
13
13
  markRefForSave(ref: PDFRef): void;
14
14
  markRefsForSave(refs: PDFRef[]): void;
@@ -33,15 +33,23 @@ declare class PDFWriter {
33
33
  * be corrected, to be accurate.
34
34
  */
35
35
  protected _largestSkippedObjectNum: number;
36
+ /**
37
+ * Used to check wheter an object should be saved or not, preserves the object number of the
38
+ * last XRef Stream object, if there is one.
39
+ */
40
+ protected _lastXRefObjectNumber: number;
36
41
  /**
37
42
  * For incremental saves, defers the decision to the snapshot.
38
- * For full saves, checks that the object is not an XRef stream object.
43
+ * For full saves, checks that the object is not the last XRef stream object.
39
44
  * @param {boolean} incremental If making an incremental save, or a full save of the PDF
40
45
  * @param {number} objNum Object number
41
- * @param {PDFObject} object PDFObject used to check if it is an XRef stream, when not 'incremental' saving
46
+ * @param {[PDFRef, PDFObject][]} objects List of objects that form the PDF
42
47
  * @returns {boolean} whether the object should be saved or not
43
48
  */
44
- protected shouldSave(incremental: boolean, objNum: number, object: PDFObject): boolean;
49
+ protected shouldSave(incremental: boolean, objNum: number, objects: [
50
+ PDFRef,
51
+ PDFObject
52
+ ][]): boolean;
45
53
  serializeToBuffer(): Promise<Uint8Array>;
46
54
  protected computeIndirectObjectSize([ref, object]: [
47
55
  PDFRef,
@@ -8,7 +8,7 @@ export declare class IncrementalDocumentSnapshot implements DocumentSnapshot {
8
8
  private lastObjectNumber;
9
9
  private changedObjects;
10
10
  context: PDFContext;
11
- constructor(lastObjectNumber: number, indirectObjects: number[], pdfSize: number, prevStartXRef: number, context: PDFContext);
11
+ constructor(lastObjectNumber: number, indirectObjects: Set<number>, pdfSize: number, prevStartXRef: number, context: PDFContext);
12
12
  shouldSave(objectNumber: number): boolean;
13
13
  markRefForSave(ref: PDFRef): void;
14
14
  markRefsForSave(refs: PDFRef[]): void;
@@ -33,15 +33,23 @@ declare class PDFWriter {
33
33
  * be corrected, to be accurate.
34
34
  */
35
35
  protected _largestSkippedObjectNum: number;
36
+ /**
37
+ * Used to check wheter an object should be saved or not, preserves the object number of the
38
+ * last XRef Stream object, if there is one.
39
+ */
40
+ protected _lastXRefObjectNumber: number;
36
41
  /**
37
42
  * For incremental saves, defers the decision to the snapshot.
38
- * For full saves, checks that the object is not an XRef stream object.
43
+ * For full saves, checks that the object is not the last XRef stream object.
39
44
  * @param {boolean} incremental If making an incremental save, or a full save of the PDF
40
45
  * @param {number} objNum Object number
41
- * @param {PDFObject} object PDFObject used to check if it is an XRef stream, when not 'incremental' saving
46
+ * @param {[PDFRef, PDFObject][]} objects List of objects that form the PDF
42
47
  * @returns {boolean} whether the object should be saved or not
43
48
  */
44
- protected shouldSave(incremental: boolean, objNum: number, object: PDFObject): boolean;
49
+ protected shouldSave(incremental: boolean, objNum: number, objects: [
50
+ PDFRef,
51
+ PDFObject
52
+ ][]): boolean;
45
53
  serializeToBuffer(): Promise<Uint8Array>;
46
54
  protected computeIndirectObjectSize([ref, object]: [
47
55
  PDFRef,