@ironsoftware/ironpdf 2026.5.1 → 2026.7.2

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 (103) hide show
  1. package/package.json +8 -5
  2. package/src/index.d.ts +1 -0
  3. package/src/index.d.ts.map +1 -1
  4. package/src/index.js +1 -0
  5. package/src/index.js.map +1 -1
  6. package/src/index.ts +1 -0
  7. package/src/internal/IronPdfEngine.ProtoFiles/iron_pdf_service.proto +5 -0
  8. package/src/internal/IronPdfEngine.ProtoFiles/pdfium_compress.proto +1 -0
  9. package/src/internal/IronPdfEngine.ProtoFiles/pdfium_form.proto +32 -0
  10. package/src/internal/IronPdfEngine.ProtoFiles/qpdf.proto +35 -0
  11. package/src/internal/access.d.ts.map +1 -1
  12. package/src/internal/access.js +3 -0
  13. package/src/internal/access.js.map +1 -1
  14. package/src/internal/access.ts +4 -0
  15. package/src/internal/generated_proto/iron_pdf_service.d.ts +14 -0
  16. package/src/internal/generated_proto/iron_pdf_service.d.ts.map +1 -1
  17. package/src/internal/generated_proto/iron_pdf_service.ts +14 -0
  18. package/src/internal/generated_proto/ironpdfengineproto/IronPdfService.d.ts +38 -0
  19. package/src/internal/generated_proto/ironpdfengineproto/IronPdfService.d.ts.map +1 -1
  20. package/src/internal/generated_proto/ironpdfengineproto/IronPdfService.ts +46 -0
  21. package/src/internal/generated_proto/ironpdfengineproto/PdfiumCompressImagesRequestP.d.ts +2 -0
  22. package/src/internal/generated_proto/ironpdfengineproto/PdfiumCompressImagesRequestP.d.ts.map +1 -1
  23. package/src/internal/generated_proto/ironpdfengineproto/PdfiumCompressImagesRequestP.ts +2 -0
  24. package/src/internal/generated_proto/ironpdfengineproto/PdfiumDisableFormFontFallbackRequestP.d.ts +8 -0
  25. package/src/internal/generated_proto/ironpdfengineproto/PdfiumDisableFormFontFallbackRequestP.d.ts.map +1 -0
  26. package/src/internal/generated_proto/ironpdfengineproto/PdfiumDisableFormFontFallbackRequestP.js +4 -0
  27. package/src/internal/generated_proto/ironpdfengineproto/PdfiumDisableFormFontFallbackRequestP.js.map +1 -0
  28. package/src/internal/generated_proto/ironpdfengineproto/PdfiumDisableFormFontFallbackRequestP.ts +11 -0
  29. package/src/internal/generated_proto/ironpdfengineproto/PdfiumDisableFormFontFallbackResultP.d.ts +12 -0
  30. package/src/internal/generated_proto/ironpdfengineproto/PdfiumDisableFormFontFallbackResultP.d.ts.map +1 -0
  31. package/src/internal/generated_proto/ironpdfengineproto/PdfiumDisableFormFontFallbackResultP.js +4 -0
  32. package/src/internal/generated_proto/ironpdfengineproto/PdfiumDisableFormFontFallbackResultP.js.map +1 -0
  33. package/src/internal/generated_proto/ironpdfengineproto/PdfiumDisableFormFontFallbackResultP.ts +15 -0
  34. package/src/internal/generated_proto/ironpdfengineproto/PdfiumSetFormFontRequestStreamP.d.ts +25 -0
  35. package/src/internal/generated_proto/ironpdfengineproto/PdfiumSetFormFontRequestStreamP.d.ts.map +1 -0
  36. package/src/internal/generated_proto/ironpdfengineproto/PdfiumSetFormFontRequestStreamP.js +4 -0
  37. package/src/internal/generated_proto/ironpdfengineproto/PdfiumSetFormFontRequestStreamP.js.map +1 -0
  38. package/src/internal/generated_proto/ironpdfengineproto/PdfiumSetFormFontRequestStreamP.ts +28 -0
  39. package/src/internal/generated_proto/ironpdfengineproto/PdfiumSetFormFontResultP.d.ts +12 -0
  40. package/src/internal/generated_proto/ironpdfengineproto/PdfiumSetFormFontResultP.d.ts.map +1 -0
  41. package/src/internal/generated_proto/ironpdfengineproto/PdfiumSetFormFontResultP.js +4 -0
  42. package/src/internal/generated_proto/ironpdfengineproto/PdfiumSetFormFontResultP.js.map +1 -0
  43. package/src/internal/generated_proto/ironpdfengineproto/PdfiumSetFormFontResultP.ts +15 -0
  44. package/src/internal/generated_proto/ironpdfengineproto/QPdfCompressAndSaveAsAdvancedFromBytesRequestStreamP.d.ts +23 -0
  45. package/src/internal/generated_proto/ironpdfengineproto/QPdfCompressAndSaveAsAdvancedFromBytesRequestStreamP.d.ts.map +1 -0
  46. package/src/internal/generated_proto/ironpdfengineproto/QPdfCompressAndSaveAsAdvancedFromBytesRequestStreamP.js +4 -0
  47. package/src/internal/generated_proto/ironpdfengineproto/QPdfCompressAndSaveAsAdvancedFromBytesRequestStreamP.js.map +1 -0
  48. package/src/internal/generated_proto/ironpdfengineproto/QPdfCompressAndSaveAsAdvancedFromBytesRequestStreamP.ts +26 -0
  49. package/src/internal/generated_proto/ironpdfengineproto/QPdfCompressAndSaveAsAdvancedRequestP.d.ts +15 -0
  50. package/src/internal/generated_proto/ironpdfengineproto/QPdfCompressAndSaveAsAdvancedRequestP.d.ts.map +1 -0
  51. package/src/internal/generated_proto/ironpdfengineproto/QPdfCompressAndSaveAsAdvancedRequestP.js +4 -0
  52. package/src/internal/generated_proto/ironpdfengineproto/QPdfCompressAndSaveAsAdvancedRequestP.js.map +1 -0
  53. package/src/internal/generated_proto/ironpdfengineproto/QPdfCompressAndSaveAsAdvancedRequestP.ts +18 -0
  54. package/src/internal/generated_proto/ironpdfengineproto/QPdfCompressionFlagsP.d.ts +30 -0
  55. package/src/internal/generated_proto/ironpdfengineproto/QPdfCompressionFlagsP.d.ts.map +1 -0
  56. package/src/internal/generated_proto/ironpdfengineproto/QPdfCompressionFlagsP.js +4 -0
  57. package/src/internal/generated_proto/ironpdfengineproto/QPdfCompressionFlagsP.js.map +1 -0
  58. package/src/internal/generated_proto/ironpdfengineproto/QPdfCompressionFlagsP.ts +33 -0
  59. package/src/internal/grpc_layer/pdfium/compress.d.ts +41 -1
  60. package/src/internal/grpc_layer/pdfium/compress.d.ts.map +1 -1
  61. package/src/internal/grpc_layer/pdfium/compress.js +220 -9
  62. package/src/internal/grpc_layer/pdfium/compress.js.map +1 -1
  63. package/src/internal/grpc_layer/pdfium/compress.ts +264 -2
  64. package/src/internal/grpc_layer/pdfium/form.d.ts +15 -0
  65. package/src/internal/grpc_layer/pdfium/form.d.ts.map +1 -0
  66. package/src/internal/grpc_layer/pdfium/form.js +99 -0
  67. package/src/internal/grpc_layer/pdfium/form.js.map +1 -0
  68. package/src/internal/grpc_layer/pdfium/form.ts +119 -0
  69. package/src/internal/grpc_layer/pdfium/formFontValidator.d.ts +26 -0
  70. package/src/internal/grpc_layer/pdfium/formFontValidator.d.ts.map +1 -0
  71. package/src/internal/grpc_layer/pdfium/formFontValidator.js +81 -0
  72. package/src/internal/grpc_layer/pdfium/formFontValidator.js.map +1 -0
  73. package/src/internal/grpc_layer/pdfium/formFontValidator.ts +86 -0
  74. package/src/internal/grpc_layer/pdfium/io.d.ts +2 -1
  75. package/src/internal/grpc_layer/pdfium/io.d.ts.map +1 -1
  76. package/src/internal/grpc_layer/pdfium/io.js +41 -36
  77. package/src/internal/grpc_layer/pdfium/io.js.map +1 -1
  78. package/src/internal/grpc_layer/pdfium/io.ts +43 -36
  79. package/src/internal/grpc_layer/pdfium/signing.d.ts +29 -2
  80. package/src/internal/grpc_layer/pdfium/signing.d.ts.map +1 -1
  81. package/src/internal/grpc_layer/pdfium/signing.js +28 -10
  82. package/src/internal/grpc_layer/pdfium/signing.js.map +1 -1
  83. package/src/internal/grpc_layer/pdfium/signing.ts +51 -11
  84. package/src/internal/image_codec.d.ts +20 -0
  85. package/src/internal/image_codec.d.ts.map +1 -0
  86. package/src/internal/image_codec.js +127 -0
  87. package/src/internal/image_codec.js.map +1 -0
  88. package/src/internal/image_codec.ts +108 -0
  89. package/src/public/compression.d.ts +92 -0
  90. package/src/public/compression.d.ts.map +1 -0
  91. package/src/public/compression.js +26 -0
  92. package/src/public/compression.js.map +1 -0
  93. package/src/public/compression.ts +107 -0
  94. package/src/public/ironpdfglobalconfig.d.ts +12 -0
  95. package/src/public/ironpdfglobalconfig.d.ts.map +1 -1
  96. package/src/public/ironpdfglobalconfig.js +7 -0
  97. package/src/public/ironpdfglobalconfig.js.map +1 -1
  98. package/src/public/ironpdfglobalconfig.ts +19 -0
  99. package/src/public/pdfDocument.d.ts +81 -0
  100. package/src/public/pdfDocument.d.ts.map +1 -1
  101. package/src/public/pdfDocument.js +212 -24
  102. package/src/public/pdfDocument.js.map +1 -1
  103. package/src/public/pdfDocument.ts +228 -28
@@ -67,7 +67,10 @@ import {mergePdfs, renderHtmlToPdf, renderHtmlZipToPdf, renderUrlToPdf, renderHt
67
67
  import {disposePdf, getBinaryData, openPdfFileBuffer} from "../internal/grpc_layer/pdfium/io";
68
68
  import {Access} from "../internal/access";
69
69
  import {renderImagesBufferToPdf, renderImagesFilesToPdf} from "../internal/grpc_layer/chrome/image";
70
- import {compressAndSaveAs, compressImage, compressInMemory, compressInMemoryStream, compressStructTree} from "../internal/grpc_layer/pdfium/compress";
70
+ import {compressAndSaveAs, compressImage, compressInMemory, compressInMemoryStream, compressStructTree, compressAndSaveAsAdvanced, compressAndSaveAsAdvancedFromBytes} from "../internal/grpc_layer/pdfium/compress";
71
+ import {disableFormFontFallback, setFormFont} from "../internal/grpc_layer/pdfium/form";
72
+ import {AdvancedCompressionOptions} from "./compression";
73
+ import * as path from "path";
71
74
  import {
72
75
  isLinearizedFromBytes,
73
76
  linearizeCoreFromBytes,
@@ -88,11 +91,11 @@ import {
88
91
  setPageRotation
89
92
  } from "../internal/grpc_layer/pdfium/page";
90
93
  import {extractRawImages, rasterizeToImageBuffers} from "../internal/grpc_layer/pdfium/image";
91
- import Jimp from "jimp";
94
+ import {transcodeImage, writeImageFile} from "../internal/image_codec";
92
95
  import {extractAllText, replaceText} from "../internal/grpc_layer/pdfium/text";
93
96
  import {PdfAVersions, PdfUAVersions, toPdfA, toPdfUA, toPdfUAForScreenReader} from "../internal/grpc_layer/pdfium/pdfa";
94
97
  import {getMetadataDict, removeMetadata, setMetadata, setMetadataDict} from "../internal/grpc_layer/pdfium/metadata";
95
- import {getSignatureCount, getVerifiedSignatures, signPdf} from "../internal/grpc_layer/pdfium/signing";
98
+ import {getSignatureCount, getVerifiedSignatures, PendingSignature, resolveCertificateBuffer, signPdf} from "../internal/grpc_layer/pdfium/signing";
96
99
  import {addHtmlAffix, addTextAffix} from "../internal/grpc_layer/pdfium/headerFooter";
97
100
  import {stampBarcode, stampHtml, stampImage, stampText} from "../internal/grpc_layer/chrome/stamp";
98
101
  import {addBackgroundForeground} from "../internal/grpc_layer/pdfium/BackgroundForeground";
@@ -471,6 +474,117 @@ export class PdfDocument{
471
474
  (filePath, imageQuality);
472
475
  }
473
476
 
477
+ /**
478
+ * Apply the advanced compression pipeline and save the result to a file.
479
+ *
480
+ * Combines pdfium-side image DPI downsampling with qpdf-side structural
481
+ * optimization in a single call.
482
+ *
483
+ * @param filePath the file path to save the compressed PDF
484
+ * @param options advanced compression options; pass an empty object `{}` to
485
+ * reproduce the legacy compressAndSaveAs behaviour with no
486
+ * image downsampling
487
+ * @param password the PDF password (empty string if none)
488
+ */
489
+ public async compressAndSaveAsAdvanced(
490
+ filePath: string,
491
+ options: AdvancedCompressionOptions,
492
+ password?: string
493
+ ): Promise<void> {
494
+ return this.internal_compressAndSaveAsAdvanced(filePath, options, password);
495
+ }
496
+
497
+ /**
498
+ * Apply the advanced compression pipeline to byte[] input and save the
499
+ * compressed result to a file. Returns the compressed bytes as well.
500
+ */
501
+ public static async compressAndSaveAsAdvancedFromBytes(
502
+ pdfBytes: Buffer,
503
+ filePath: string,
504
+ options: AdvancedCompressionOptions,
505
+ password?: string
506
+ ): Promise<Buffer> {
507
+ if (!pdfBytes || pdfBytes.length === 0) {
508
+ throw new Error("pdfBytes must not be null or empty");
509
+ }
510
+ if (!options) {
511
+ throw new Error("options must not be null");
512
+ }
513
+ return compressAndSaveAsAdvancedFromBytes(pdfBytes, filePath, options, password ?? "");
514
+ }
515
+
516
+ //#endregion
517
+
518
+ //#region form (PDF-2184)
519
+
520
+ /**
521
+ * Set the document-wide form font for subsequent form-field fills. When
522
+ * set, the engine skips its automatic Tahoma/Arial fallback embed for
523
+ * non-ASCII form values and registers the supplied font in the AcroForm
524
+ * /DR /Font dictionary so default-appearance strings resolve correctly
525
+ * at render time.
526
+ *
527
+ * File-size impact:
528
+ * - Name-only mode (`fontData` omitted or empty): zero bytes added; the
529
+ * font must already be in the document.
530
+ * - Bytes mode and the font is already embedded with usable glyph data:
531
+ * zero bytes added.
532
+ * - Bytes mode and the font is missing or has no glyph data: the full
533
+ * font is embedded.
534
+ * - Bytes mode with `forceEmbed = true`: a fresh font copy is added
535
+ * alongside any existing copy; the document grows on every call.
536
+ *
537
+ * @param fontName PDF font name to register (e.g. "Poppins-Regular").
538
+ * Allowed characters: letters, digits, `_`, `-`, `.`, `+`.
539
+ * @param fontData Raw TrueType/OpenType bytes; pass `undefined` or an
540
+ * empty Buffer for name-only mode.
541
+ * @param forceEmbed When true, embed `fontData` even if a font with the
542
+ * same name and usable glyph data is already present.
543
+ */
544
+ public async setFormFont(
545
+ fontName: string,
546
+ fontData?: Buffer,
547
+ forceEmbed = false
548
+ ): Promise<void> {
549
+ return setFormFont(await this.internal_getId(), fontName, fontData, forceEmbed);
550
+ }
551
+
552
+ /**
553
+ * Load a TrueType/OpenType font from disk and apply it as the
554
+ * document-wide form font. The PDF font name is derived from the file
555
+ * name (without extension) when `fontName` is omitted.
556
+ *
557
+ * @param fontFilePath Path to a TTF/OTF/TTC font file
558
+ * @param fontName Optional PDF font name. When omitted the file name
559
+ * (without extension) is used.
560
+ * @param forceEmbed When true, embed even if the font is already present.
561
+ */
562
+ public async setFormFontFromFile(
563
+ fontFilePath: string,
564
+ fontName?: string,
565
+ forceEmbed = false
566
+ ): Promise<void> {
567
+ if (!fontFilePath) {
568
+ throw new Error("fontFilePath must not be empty");
569
+ }
570
+ const fontData = fs.readFileSync(fontFilePath);
571
+ const resolvedName = fontName ?? deriveFontNameFromPath(fontFilePath);
572
+ return setFormFont(await this.internal_getId(), resolvedName, fontData, forceEmbed);
573
+ }
574
+
575
+ /**
576
+ * Suppress the automatic Tahoma/Arial fallback embed for non-ASCII form
577
+ * values without registering any replacement font. Use when zero
578
+ * file-size growth is required and the template's existing font
579
+ * references are sufficient for the values being filled.
580
+ *
581
+ * Rendering of non-ASCII characters then depends entirely on the
582
+ * viewer's font substitution.
583
+ */
584
+ public async disableFormFontFallback(): Promise<void> {
585
+ return disableFormFontFallback(await this.internal_getId());
586
+ }
587
+
474
588
  //#endregion
475
589
 
476
590
  //#region linearize
@@ -1378,6 +1492,13 @@ export class PdfDocument{
1378
1492
  * @private
1379
1493
  */
1380
1494
  private pdfPassword?: PdfPassword | undefined;
1495
+ /**
1496
+ * Digital signatures whose placeholder fields have been added (via
1497
+ * {@link signDigitalSignature}) but still need to be cryptographically finalized when the
1498
+ * document is saved. See {@link internal_saveAsBuffer}.
1499
+ * @private
1500
+ */
1501
+ private pendingSignatures: PendingSignature[] = [];
1381
1502
 
1382
1503
  /**
1383
1504
  * Create a PdfDocument object from a {@link PdfInput}
@@ -1746,7 +1867,7 @@ export class PdfDocument{
1746
1867
  * @param saveOptions see {@link SaveOptions}
1747
1868
  */
1748
1869
  private async internal_saveAsBuffer(saveOptions?: SaveOptions | undefined): Promise<Buffer> {
1749
- return getBinaryData(await this.internal_getId(), saveOptions);
1870
+ return getBinaryData(await this.internal_getId(), saveOptions, this.pendingSignatures);
1750
1871
  }
1751
1872
 
1752
1873
  //#endregion
@@ -1839,6 +1960,34 @@ export class PdfDocument{
1839
1960
  );
1840
1961
  }
1841
1962
 
1963
+ private async internal_compressAndSaveAsAdvanced(
1964
+ filePath: string,
1965
+ options: AdvancedCompressionOptions,
1966
+ password?: string
1967
+ ): Promise<void> {
1968
+ if (!filePath || filePath.trim().length === 0) {
1969
+ throw new Error("filePath must not be empty");
1970
+ }
1971
+ if (!options) {
1972
+ throw new Error("options must not be null");
1973
+ }
1974
+ if (
1975
+ options.jpegQuality !== undefined &&
1976
+ options.jpegQuality !== null &&
1977
+ (options.jpegQuality < 1 || options.jpegQuality > 100)
1978
+ ) {
1979
+ throw new Error(
1980
+ `Invalid jpegQuality (${options.jpegQuality}). Must be between 1 and 100.`
1981
+ );
1982
+ }
1983
+ return await compressAndSaveAsAdvanced(
1984
+ await this.internal_getId(),
1985
+ filePath,
1986
+ options,
1987
+ password ?? ""
1988
+ );
1989
+ }
1990
+
1842
1991
  //#endregion
1843
1992
 
1844
1993
  //#region linearize
@@ -2119,25 +2268,7 @@ export class PdfDocument{
2119
2268
  await this.internal_getId(),
2120
2269
  options?.fromPages ?? "all"
2121
2270
  );
2122
- const jimpImageType: "image/bmp" | "image/png" | "image/jpeg" = (() => {
2123
- switch (options?.imageType) {
2124
- case ImageType.BMP:
2125
- return Jimp.MIME_BMP;
2126
- case ImageType.PNG:
2127
- return Jimp.MIME_PNG;
2128
- case ImageType.JPG:
2129
- return Jimp.MIME_JPEG;
2130
- default:
2131
- return Jimp.MIME_PNG;
2132
- }
2133
- })();
2134
- return Promise.all(
2135
- images.map(async (imageBuffer) => {
2136
- //convert output type
2137
- const jimp = await Jimp.read(imageBuffer);
2138
- return await jimp.getBufferAsync(jimpImageType);
2139
- })
2140
- );
2271
+ return images.map((imageBuffer) => transcodeImage(imageBuffer, options?.imageType));
2141
2272
  }
2142
2273
 
2143
2274
  /**
@@ -2169,9 +2300,7 @@ export class PdfDocument{
2169
2300
 
2170
2301
  const promises = images.map(async (imageBuffer, index) => {
2171
2302
  const outputFileName = getFileName(filePath,index.toString(),getImageExtType(options?.type),"image");
2172
- await Jimp.read(imageBuffer).then((value) => {
2173
- return value.write(outputFileName);
2174
- });
2303
+ await writeImageFile(imageBuffer, outputFileName, options?.type);
2175
2304
  return outputFileName;
2176
2305
  });
2177
2306
 
@@ -2273,7 +2402,64 @@ export class PdfDocument{
2273
2402
  * @param signature see {@link DigitalSignature}
2274
2403
  */
2275
2404
  private async internal_signDigitalSignature(signature: DigitalSignature) {
2276
- return await signPdf(await this.internal_getId(), signature);
2405
+ // Resolve the certificate up-front: signing finalizes at save time and the certificate
2406
+ // has to be re-sent then (see internal_saveAsBuffer / getBinaryData). If we cannot resolve
2407
+ // it we must fail before reserving a placeholder on the engine, otherwise we would be left
2408
+ // with an un-fillable placeholder that silently produces an invalid signature on save.
2409
+ const certificate = resolveCertificateBuffer(signature);
2410
+ if (!certificate) {
2411
+ throw new Error(
2412
+ "A signing certificate is required: provide either certificatePath or certificateBuffer."
2413
+ );
2414
+ }
2415
+
2416
+ // Multiple signatures cannot be finalized in a single save: filling a later signature's
2417
+ // placeholder rewrites bytes that an earlier signature already covers, which invalidates
2418
+ // the earlier one. So whenever a signature from a previous signDigitalSignature() call is
2419
+ // still pending, finalize it first (save + re-open) so the new signature is applied as a
2420
+ // separate revision. This is the sign -> save -> re-open -> sign flow done transparently,
2421
+ // and it keeps every signature valid.
2422
+ await this.internal_finalizePendingSignatures();
2423
+
2424
+ // Reuse the already-resolved certificate so signPdf does not read the file a second time.
2425
+ const index = await signPdf(await this.internal_getId(), {
2426
+ ...signature,
2427
+ certificateBuffer: certificate,
2428
+ });
2429
+
2430
+ // The signature field is only a placeholder until the document is saved. Remember the
2431
+ // certificate so it can be re-sent to finalize the signing in internal_saveAsBuffer().
2432
+ // At most one signature is ever pending here (earlier ones have already been finalized
2433
+ // above), so each save only ever finalizes a single signature.
2434
+ this.pendingSignatures.push({
2435
+ index,
2436
+ password: signature.certificatePassword ?? "",
2437
+ timeStampUrl: signature.timeStampUrl ?? "",
2438
+ certificate,
2439
+ });
2440
+ }
2441
+
2442
+ /**
2443
+ * Finalizes any currently-pending digital signatures into the document by saving it (which
2444
+ * fills the reserved placeholders) and re-opening the result, then swapping in the new
2445
+ * engine-side document. This isolates each signature in its own revision so that adding a
2446
+ * further signature does not invalidate the previous ones. No-op when nothing is pending.
2447
+ * @private
2448
+ */
2449
+ private async internal_finalizePendingSignatures(): Promise<void> {
2450
+ if (this.pendingSignatures.length === 0) {
2451
+ return;
2452
+ }
2453
+ const finalized = await getBinaryData(
2454
+ await this.internal_getId(),
2455
+ undefined,
2456
+ this.pendingSignatures
2457
+ );
2458
+ this.pendingSignatures = [];
2459
+ this.pdfDocumentId = await openPdfFileBuffer(finalized, {
2460
+ userPassword: this.pdfPassword?.userPassword,
2461
+ ownerPassword: this.pdfPassword?.ownerPassword,
2462
+ });
2277
2463
  }
2278
2464
 
2279
2465
  /**
@@ -2295,7 +2481,10 @@ export class PdfDocument{
2295
2481
  * Get all verified digital signatures from this PdfDocument.
2296
2482
  */
2297
2483
  private async internal_getVerifiedSignatures(): Promise<VerifiedSignature[]> {
2298
- return await getVerifiedSignatures(await this.internal_getId());
2484
+ // Verify against the finalized document bytes (including any pending signatures that are
2485
+ // only applied at save time), otherwise the engine re-saves and invalidates the signature.
2486
+ const data = await this.internal_saveAsBuffer();
2487
+ return await getVerifiedSignatures(await this.internal_getId(), data);
2299
2488
  }
2300
2489
 
2301
2490
  //#endregion
@@ -2570,3 +2759,14 @@ export class PdfDocument{
2570
2759
 
2571
2760
  //#endregion
2572
2761
  }
2762
+
2763
+ /**
2764
+ * Derive a PDF font name from a font file path: strip the directory and the
2765
+ * extension. Used by {@link PdfDocument.setFormFontFromFile} when no
2766
+ * explicit name is supplied.
2767
+ */
2768
+ function deriveFontNameFromPath(fontFilePath: string): string {
2769
+ const base = path.basename(fontFilePath);
2770
+ const dot = base.lastIndexOf(".");
2771
+ return dot > 0 ? base.substring(0, dot) : base;
2772
+ }