@embedpdf/engines 2.9.1 → 2.10.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 (50) hide show
  1. package/dist/{direct-engine-D-Jf9yyY.js → direct-engine-4LZYs06h.js} +1069 -262
  2. package/dist/direct-engine-4LZYs06h.js.map +1 -0
  3. package/dist/direct-engine-C29Euebw.cjs +2 -0
  4. package/dist/direct-engine-C29Euebw.cjs.map +1 -0
  5. package/dist/index.cjs +1 -1
  6. package/dist/index.cjs.map +1 -1
  7. package/dist/index.js +165 -143
  8. package/dist/index.js.map +1 -1
  9. package/dist/lib/orchestrator/pdf-engine.d.ts +8 -1
  10. package/dist/lib/orchestrator/remote-executor.d.ts +8 -1
  11. package/dist/lib/pdfium/cache.d.ts +5 -4
  12. package/dist/lib/pdfium/engine.d.ts +40 -6
  13. package/dist/lib/pdfium/index.cjs +1 -1
  14. package/dist/lib/pdfium/index.cjs.map +1 -1
  15. package/dist/lib/pdfium/index.js +3 -3
  16. package/dist/lib/pdfium/web/direct-engine.cjs +1 -1
  17. package/dist/lib/pdfium/web/direct-engine.js +2 -2
  18. package/dist/lib/pdfium/web/worker-engine.cjs +1 -1
  19. package/dist/lib/pdfium/web/worker-engine.cjs.map +1 -1
  20. package/dist/lib/pdfium/web/worker-engine.js +32 -2
  21. package/dist/lib/pdfium/web/worker-engine.js.map +1 -1
  22. package/dist/lib/webworker/engine.cjs +1 -1
  23. package/dist/lib/webworker/engine.cjs.map +1 -1
  24. package/dist/lib/webworker/engine.d.ts +19 -1
  25. package/dist/lib/webworker/engine.js +104 -0
  26. package/dist/lib/webworker/engine.js.map +1 -1
  27. package/dist/lib/webworker/runner.d.ts +19 -5
  28. package/dist/pdf-engine-BeHgaBOW.cjs +2 -0
  29. package/dist/pdf-engine-BeHgaBOW.cjs.map +1 -0
  30. package/dist/{pdf-engine-ZvReuoDb.js → pdf-engine-sORqXhQk.js} +74 -1
  31. package/dist/pdf-engine-sORqXhQk.js.map +1 -0
  32. package/dist/preact/index.cjs +1 -1
  33. package/dist/preact/index.cjs.map +1 -1
  34. package/dist/preact/index.js +1 -1
  35. package/dist/react/index.cjs +1 -1
  36. package/dist/react/index.cjs.map +1 -1
  37. package/dist/react/index.js +1 -1
  38. package/dist/svelte/index.cjs +1 -1
  39. package/dist/svelte/index.cjs.map +1 -1
  40. package/dist/svelte/index.js +1 -1
  41. package/dist/vue/index.cjs +1 -1
  42. package/dist/vue/index.cjs.map +1 -1
  43. package/dist/vue/index.js +1 -1
  44. package/package.json +7 -7
  45. package/dist/direct-engine-CDxs18JK.cjs +0 -2
  46. package/dist/direct-engine-CDxs18JK.cjs.map +0 -1
  47. package/dist/direct-engine-D-Jf9yyY.js.map +0 -1
  48. package/dist/pdf-engine-DeyImjZt.cjs +0 -2
  49. package/dist/pdf-engine-DeyImjZt.cjs.map +0 -1
  50. package/dist/pdf-engine-ZvReuoDb.js.map +0 -1
@@ -1,6 +1,6 @@
1
1
  import { init } from "@embedpdf/pdfium";
2
- import { Rotation, NoopLogger, PdfTaskHelper, PdfErrorCode, pdfDateToDate, isUuidV4, uuidV4, PdfAnnotationSubtype, PdfPageFlattenFlag, stripPdfUnwantedMarkers, PdfAnnotationIcon, PdfAnnotationColorType, PdfAnnotationBorderStyle, PdfAnnotationLineEnding, PdfStandardFont, PdfStampFit, PdfTrappedStatus, pdfColorToWebColor, webColorToPdfColor, pdfAlphaToWebOpacity, webOpacityToPdfAlpha, PdfAnnotationReplyType, dateToPdfDate, quadToRect, rectToQuad, PdfPageObjectType, flagsToNames, namesToFlags, PDF_FORM_FIELD_TYPE, AppearanceMode, Task, toIntRect, transformRect, buildUserToDeviceMatrix, AP_MODE_NORMAL, AP_MODE_ROLLOVER, AP_MODE_DOWN, PdfZoomMode, PdfActionType } from "@embedpdf/models";
3
- import { P as PdfEngine } from "./pdf-engine-ZvReuoDb.js";
2
+ import { Rotation, NoopLogger, PdfTaskHelper, PdfErrorCode, pdfDateToDate, PdfJavaScriptActionTrigger, PdfAnnotationSubtype, isUuidV4, uuidV4, PdfJavaScriptWidgetEventType, PDF_ANNOT_AACTION_EVENT, PDF_FORM_FIELD_TYPE, PdfPageFlattenFlag, stripPdfUnwantedMarkers, PdfAnnotationIcon, PdfAnnotationColorType, PdfAnnotationBorderStyle, PdfStandardFont, PDF_FORM_FIELD_FLAG, webColorToPdfColor, pdfColorToWebColor, PdfAnnotationLineEnding, PdfStampFit, PdfTrappedStatus, pdfAlphaToWebOpacity, webOpacityToPdfAlpha, PdfAnnotationReplyType, dateToPdfDate, quadToRect, rectToQuad, PdfPageObjectType, flagsToNames, namesToFlags, AppearanceMode, Task, toIntRect, transformRect, buildUserToDeviceMatrix, AP_MODE_NORMAL, AP_MODE_ROLLOVER, AP_MODE_DOWN, PdfZoomMode, PdfActionType } from "@embedpdf/models";
3
+ import { P as PdfEngine } from "./pdf-engine-sORqXhQk.js";
4
4
  import { b as browserImageDataToBlobConverter } from "./browser-BISJ9naB.js";
5
5
  function readString(wasmModule, readChars, parseChars, defaultLength = 100) {
6
6
  let buffer = wasmModule.wasmExports.malloc(defaultLength);
@@ -335,13 +335,6 @@ class PageContext {
335
335
  if (this.textPagePtr !== void 0) {
336
336
  this.pdf.FPDFText_ClosePage(this.textPagePtr);
337
337
  }
338
- if (this.formHandle !== void 0) {
339
- this.pdf.FORM_OnBeforeClosePage(this.pagePtr, this.formHandle);
340
- this.pdf.PDFiumExt_ExitFormFillEnvironment(this.formHandle);
341
- }
342
- if (this.formInfoPtr !== void 0) {
343
- this.pdf.PDFiumExt_CloseFormFillInfo(this.formInfoPtr);
344
- }
345
338
  this.pdf.FPDF_ClosePage(this.pagePtr);
346
339
  this.onFinalDispose();
347
340
  }
@@ -354,16 +347,6 @@ class PageContext {
354
347
  }
355
348
  return this.textPagePtr;
356
349
  }
357
- /** Always safe: opens (once) and returns the form-fill handle. */
358
- getFormHandle() {
359
- this.ensureAlive();
360
- if (this.formHandle === void 0) {
361
- this.formInfoPtr = this.pdf.PDFiumExt_OpenFormFillInfo();
362
- this.formHandle = this.pdf.PDFiumExt_InitFormFillEnvironment(this.docPtr, this.formInfoPtr);
363
- this.pdf.FORM_OnAfterLoadPage(this.pagePtr, this.formHandle);
364
- }
365
- return this.formHandle;
366
- }
367
350
  /**
368
351
  * Safely execute `fn` with an annotation pointer.
369
352
  * Pointer is ALWAYS closed afterwards.
@@ -377,6 +360,23 @@ class PageContext {
377
360
  this.pdf.FPDFPage_CloseAnnot(annotPtr);
378
361
  }
379
362
  }
363
+ /**
364
+ * Safely execute `fn` with a fresh form-fill handle.
365
+ * Handle is ALWAYS torn down afterwards — no caching, no stale state.
366
+ */
367
+ withFormHandle(fn) {
368
+ this.ensureAlive();
369
+ const formInfoPtr = this.pdf.PDFiumExt_OpenFormFillInfo();
370
+ const formHandle = this.pdf.PDFiumExt_InitFormFillEnvironment(this.docPtr, formInfoPtr);
371
+ this.pdf.FORM_OnAfterLoadPage(this.pagePtr, formHandle);
372
+ try {
373
+ return fn(formHandle);
374
+ } finally {
375
+ this.pdf.FORM_OnBeforeClosePage(this.pagePtr, formHandle);
376
+ this.pdf.PDFiumExt_ExitFormFillEnvironment(formHandle);
377
+ this.pdf.PDFiumExt_CloseFormFillInfo(formInfoPtr);
378
+ }
379
+ }
380
380
  ensureAlive() {
381
381
  if (this.disposed) throw new Error("PageContext already disposed");
382
382
  }
@@ -1452,6 +1452,202 @@ class PdfiumNative {
1452
1452
  this.logger.perf(LOG_SOURCE, LOG_CATEGORY, `RenderPageRect`, "End", `${doc.id}-${page.index}`);
1453
1453
  return task;
1454
1454
  }
1455
+ getDocumentJavaScriptActions(doc) {
1456
+ this.logger.debug(LOG_SOURCE, LOG_CATEGORY, "getDocumentJavaScriptActions", doc);
1457
+ const ctx = this.cache.getContext(doc.id);
1458
+ if (!ctx) {
1459
+ return PdfTaskHelper.reject({
1460
+ code: PdfErrorCode.DocNotOpen,
1461
+ message: "document does not open"
1462
+ });
1463
+ }
1464
+ const count = this.pdfiumModule.FPDFDoc_GetJavaScriptActionCount(ctx.docPtr);
1465
+ if (count < 0) {
1466
+ return PdfTaskHelper.reject({
1467
+ code: PdfErrorCode.Unknown,
1468
+ message: "failed to read document javascript actions"
1469
+ });
1470
+ }
1471
+ const actions = [];
1472
+ for (let index = 0; index < count; index++) {
1473
+ const actionPtr = this.pdfiumModule.FPDFDoc_GetJavaScriptAction(ctx.docPtr, index);
1474
+ if (!actionPtr) continue;
1475
+ try {
1476
+ const name = readString(
1477
+ this.pdfiumModule.pdfium,
1478
+ (buffer, bufferLength) => this.pdfiumModule.FPDFJavaScriptAction_GetName(actionPtr, buffer, bufferLength),
1479
+ this.pdfiumModule.pdfium.UTF16ToString
1480
+ ) ?? "";
1481
+ const script = readString(
1482
+ this.pdfiumModule.pdfium,
1483
+ (buffer, bufferLength) => this.pdfiumModule.FPDFJavaScriptAction_GetScript(actionPtr, buffer, bufferLength),
1484
+ this.pdfiumModule.pdfium.UTF16ToString
1485
+ ) ?? "";
1486
+ if (!script) continue;
1487
+ actions.push({
1488
+ id: `document:${index}:${name}`,
1489
+ trigger: PdfJavaScriptActionTrigger.DocumentNamed,
1490
+ name,
1491
+ script
1492
+ });
1493
+ } finally {
1494
+ this.pdfiumModule.FPDFDoc_CloseJavaScriptAction(actionPtr);
1495
+ }
1496
+ }
1497
+ return PdfTaskHelper.resolve(actions);
1498
+ }
1499
+ getPageAnnoWidgets(doc, page) {
1500
+ this.logger.debug(LOG_SOURCE, LOG_CATEGORY, "getPageAnnoWidgets", doc, page);
1501
+ this.logger.perf(
1502
+ LOG_SOURCE,
1503
+ LOG_CATEGORY,
1504
+ `GetPageAnnoWidgets`,
1505
+ "Begin",
1506
+ `${doc.id}-${page.index}`
1507
+ );
1508
+ const ctx = this.cache.getContext(doc.id);
1509
+ if (!ctx) {
1510
+ this.logger.perf(
1511
+ LOG_SOURCE,
1512
+ LOG_CATEGORY,
1513
+ `GetPageAnnoWidgets`,
1514
+ "End",
1515
+ `${doc.id}-${page.index}`
1516
+ );
1517
+ return PdfTaskHelper.reject({
1518
+ code: PdfErrorCode.DocNotOpen,
1519
+ message: "document does not open"
1520
+ });
1521
+ }
1522
+ const annotationWidgets = this.readPageAnnoWidgets(doc, ctx, page);
1523
+ this.logger.perf(
1524
+ LOG_SOURCE,
1525
+ LOG_CATEGORY,
1526
+ `GetPageAnnoWidgets`,
1527
+ "End",
1528
+ `${doc.id}-${page.index}`
1529
+ );
1530
+ this.logger.debug(
1531
+ LOG_SOURCE,
1532
+ LOG_CATEGORY,
1533
+ `GetPageAnnoWidgets`,
1534
+ `${doc.id}-${page.index}`,
1535
+ annotationWidgets
1536
+ );
1537
+ return PdfTaskHelper.resolve(annotationWidgets);
1538
+ }
1539
+ getPageWidgetJavaScriptActions(doc, page) {
1540
+ this.logger.debug(LOG_SOURCE, LOG_CATEGORY, "getPageWidgetJavaScriptActions", doc, page);
1541
+ const ctx = this.cache.getContext(doc.id);
1542
+ if (!ctx) {
1543
+ return PdfTaskHelper.reject({
1544
+ code: PdfErrorCode.DocNotOpen,
1545
+ message: "document does not open"
1546
+ });
1547
+ }
1548
+ const actions = [];
1549
+ ctx.borrowPage(page.index, (pageCtx) => {
1550
+ pageCtx.withFormHandle((formHandle) => {
1551
+ const annotCount = this.pdfiumModule.FPDFPage_GetAnnotCount(pageCtx.pagePtr);
1552
+ for (let i = 0; i < annotCount; i++) {
1553
+ pageCtx.withAnnotation(i, (annotPtr) => {
1554
+ const subtype = this.pdfiumModule.FPDFAnnot_GetSubtype(
1555
+ annotPtr
1556
+ );
1557
+ if (subtype !== PdfAnnotationSubtype.WIDGET) return;
1558
+ let annotationId = this.getAnnotString(annotPtr, "NM");
1559
+ if (!annotationId || !isUuidV4(annotationId)) {
1560
+ annotationId = uuidV4();
1561
+ this.setAnnotString(annotPtr, "NM", annotationId);
1562
+ }
1563
+ const fieldName = readString(
1564
+ this.pdfiumModule.pdfium,
1565
+ (buffer, bufferLength) => this.pdfiumModule.FPDFAnnot_GetFormFieldName(
1566
+ formHandle,
1567
+ annotPtr,
1568
+ buffer,
1569
+ bufferLength
1570
+ ),
1571
+ this.pdfiumModule.pdfium.UTF16ToString
1572
+ ) ?? "";
1573
+ const eventConfigs = [
1574
+ {
1575
+ event: PDF_ANNOT_AACTION_EVENT.KEY_STROKE,
1576
+ eventType: PdfJavaScriptWidgetEventType.Keystroke,
1577
+ trigger: PdfJavaScriptActionTrigger.WidgetKeystroke
1578
+ },
1579
+ {
1580
+ event: PDF_ANNOT_AACTION_EVENT.FORMAT,
1581
+ eventType: PdfJavaScriptWidgetEventType.Format,
1582
+ trigger: PdfJavaScriptActionTrigger.WidgetFormat
1583
+ },
1584
+ {
1585
+ event: PDF_ANNOT_AACTION_EVENT.VALIDATE,
1586
+ eventType: PdfJavaScriptWidgetEventType.Validate,
1587
+ trigger: PdfJavaScriptActionTrigger.WidgetValidate
1588
+ },
1589
+ {
1590
+ event: PDF_ANNOT_AACTION_EVENT.CALCULATE,
1591
+ eventType: PdfJavaScriptWidgetEventType.Calculate,
1592
+ trigger: PdfJavaScriptActionTrigger.WidgetCalculate
1593
+ }
1594
+ ];
1595
+ for (const config of eventConfigs) {
1596
+ const script = readString(
1597
+ this.pdfiumModule.pdfium,
1598
+ (buffer, bufferLength) => this.pdfiumModule.FPDFAnnot_GetFormAdditionalActionJavaScript(
1599
+ formHandle,
1600
+ annotPtr,
1601
+ config.event,
1602
+ buffer,
1603
+ bufferLength
1604
+ ),
1605
+ this.pdfiumModule.pdfium.UTF16ToString
1606
+ ) ?? "";
1607
+ if (!script) continue;
1608
+ actions.push({
1609
+ id: `widget:${page.index}:${annotationId}:${config.eventType}`,
1610
+ trigger: config.trigger,
1611
+ eventType: config.eventType,
1612
+ pageIndex: page.index,
1613
+ annotationId,
1614
+ fieldName,
1615
+ script
1616
+ });
1617
+ }
1618
+ });
1619
+ }
1620
+ });
1621
+ });
1622
+ return PdfTaskHelper.resolve(actions);
1623
+ }
1624
+ regenerateWidgetAppearances(doc, page, annotationIds) {
1625
+ const ctx = this.cache.getContext(doc.id);
1626
+ if (!ctx) {
1627
+ return PdfTaskHelper.reject({
1628
+ code: PdfErrorCode.DocNotOpen,
1629
+ message: "document does not open"
1630
+ });
1631
+ }
1632
+ const idSet = new Set(annotationIds);
1633
+ let regenerated = 0;
1634
+ ctx.borrowPage(page.index, (pageCtx) => {
1635
+ const count = this.pdfiumModule.FPDFPage_GetAnnotCount(pageCtx.pagePtr);
1636
+ for (let i = 0; i < count; i++) {
1637
+ pageCtx.withAnnotation(i, (annotPtr) => {
1638
+ const nm = this.getAnnotString(annotPtr, "NM");
1639
+ if (nm && idSet.has(nm)) {
1640
+ this.pdfiumModule.EPDFAnnot_GenerateFormFieldAP(annotPtr);
1641
+ regenerated++;
1642
+ }
1643
+ });
1644
+ }
1645
+ if (regenerated > 0) {
1646
+ this.pdfiumModule.FPDFPage_GenerateContent(pageCtx.pagePtr);
1647
+ }
1648
+ });
1649
+ return PdfTaskHelper.resolve(regenerated > 0);
1650
+ }
1455
1651
  /**
1456
1652
  * {@inheritDoc @embedpdf/models!PdfEngine.getPageAnnotations}
1457
1653
  *
@@ -1503,6 +1699,7 @@ class PdfiumNative {
1503
1699
  * @public
1504
1700
  */
1505
1701
  createPageAnnotation(doc, page, annotation, context) {
1702
+ var _a;
1506
1703
  this.logger.debug(LOG_SOURCE, LOG_CATEGORY, "createPageAnnotation", doc, page, annotation);
1507
1704
  this.logger.perf(
1508
1705
  LOG_SOURCE,
@@ -1526,7 +1723,30 @@ class PdfiumNative {
1526
1723
  });
1527
1724
  }
1528
1725
  const pageCtx = ctx.acquirePage(page.index);
1529
- const annotationPtr = this.pdfiumModule.EPDFPage_CreateAnnot(pageCtx.pagePtr, annotation.type);
1726
+ let annotationPtr;
1727
+ let widgetFormInfoPtr;
1728
+ let widgetFormHandle;
1729
+ if (annotation.type === PdfAnnotationSubtype.WIDGET) {
1730
+ const widget = annotation;
1731
+ widgetFormInfoPtr = this.pdfiumModule.PDFiumExt_OpenFormFillInfo();
1732
+ widgetFormHandle = this.pdfiumModule.PDFiumExt_InitFormFillEnvironment(
1733
+ ctx.docPtr,
1734
+ widgetFormInfoPtr
1735
+ );
1736
+ this.pdfiumModule.FORM_OnAfterLoadPage(pageCtx.pagePtr, widgetFormHandle);
1737
+ const fieldName = ((_a = widget.field) == null ? void 0 : _a.name) ?? "";
1738
+ annotationPtr = this.withWString(
1739
+ fieldName,
1740
+ (namePtr) => this.pdfiumModule.EPDFPage_CreateFormField(
1741
+ pageCtx.pagePtr,
1742
+ widgetFormHandle,
1743
+ widget.field.type,
1744
+ namePtr
1745
+ )
1746
+ );
1747
+ } else {
1748
+ annotationPtr = this.pdfiumModule.EPDFPage_CreateAnnot(pageCtx.pagePtr, annotation.type);
1749
+ }
1530
1750
  if (!annotationPtr) {
1531
1751
  this.logger.perf(
1532
1752
  LOG_SOURCE,
@@ -1671,6 +1891,32 @@ class PdfiumNative {
1671
1891
  saveAnnotation
1672
1892
  );
1673
1893
  break;
1894
+ case PdfAnnotationSubtype.WIDGET: {
1895
+ const widget = saveAnnotation;
1896
+ if (widgetFormHandle !== void 0) {
1897
+ switch (widget.field.type) {
1898
+ case PDF_FORM_FIELD_TYPE.TEXTFIELD:
1899
+ isSucceed = this.addTextFieldContent(widgetFormHandle, annotationPtr, widget);
1900
+ break;
1901
+ case PDF_FORM_FIELD_TYPE.CHECKBOX:
1902
+ case PDF_FORM_FIELD_TYPE.RADIOBUTTON:
1903
+ isSucceed = this.addToggleFieldContent(widgetFormHandle, annotationPtr, widget);
1904
+ break;
1905
+ case PDF_FORM_FIELD_TYPE.COMBOBOX:
1906
+ case PDF_FORM_FIELD_TYPE.LISTBOX:
1907
+ isSucceed = this.addChoiceFieldContent(widgetFormHandle, annotationPtr, widget);
1908
+ break;
1909
+ }
1910
+ }
1911
+ break;
1912
+ }
1913
+ }
1914
+ if (widgetFormHandle !== void 0) {
1915
+ this.pdfiumModule.FORM_OnBeforeClosePage(pageCtx.pagePtr, widgetFormHandle);
1916
+ this.pdfiumModule.PDFiumExt_ExitFormFillEnvironment(widgetFormHandle);
1917
+ }
1918
+ if (widgetFormInfoPtr !== void 0) {
1919
+ this.pdfiumModule.PDFiumExt_CloseFormFillInfo(widgetFormInfoPtr);
1674
1920
  }
1675
1921
  if (!isSucceed) {
1676
1922
  this.pdfiumModule.FPDFPage_RemoveAnnot(pageCtx.pagePtr, annotationPtr);
@@ -1687,7 +1933,9 @@ class PdfiumNative {
1687
1933
  message: "can not add content of the annotation"
1688
1934
  });
1689
1935
  }
1690
- if (annotation.blendMode !== void 0) {
1936
+ if (annotation.type === PdfAnnotationSubtype.WIDGET) {
1937
+ this.pdfiumModule.EPDFAnnot_GenerateFormFieldAP(annotationPtr);
1938
+ } else if (annotation.blendMode !== void 0) {
1691
1939
  this.pdfiumModule.EPDFAnnot_GenerateAppearanceWithBlend(annotationPtr, annotation.blendMode);
1692
1940
  } else {
1693
1941
  this.pdfiumModule.EPDFAnnot_GenerateAppearance(annotationPtr);
@@ -1889,12 +2137,34 @@ class PdfiumNative {
1889
2137
  );
1890
2138
  break;
1891
2139
  }
2140
+ /* ── Widget (form field) ─────────────────────────────────────────────── */
2141
+ case PdfAnnotationSubtype.WIDGET: {
2142
+ const widget = saveAnnotation;
2143
+ pageCtx.withFormHandle((formHandle) => {
2144
+ switch (widget.field.type) {
2145
+ case PDF_FORM_FIELD_TYPE.TEXTFIELD:
2146
+ ok = this.addTextFieldContent(formHandle, annotPtr, widget);
2147
+ break;
2148
+ case PDF_FORM_FIELD_TYPE.CHECKBOX:
2149
+ case PDF_FORM_FIELD_TYPE.RADIOBUTTON:
2150
+ ok = this.addToggleFieldContent(formHandle, annotPtr, widget);
2151
+ break;
2152
+ case PDF_FORM_FIELD_TYPE.COMBOBOX:
2153
+ case PDF_FORM_FIELD_TYPE.LISTBOX:
2154
+ ok = this.addChoiceFieldContent(formHandle, annotPtr, widget);
2155
+ break;
2156
+ }
2157
+ });
2158
+ break;
2159
+ }
1892
2160
  /* ── Unsupported edits – fall through to error ───────────────────────── */
1893
2161
  default:
1894
2162
  ok = false;
1895
2163
  }
1896
2164
  if (ok && (options == null ? void 0 : options.regenerateAppearance) !== false) {
1897
- if (annotation.blendMode !== void 0) {
2165
+ if (annotation.type === PdfAnnotationSubtype.WIDGET) {
2166
+ this.pdfiumModule.EPDFAnnot_GenerateFormFieldAP(annotPtr);
2167
+ } else if (annotation.blendMode !== void 0) {
1898
2168
  this.pdfiumModule.EPDFAnnot_GenerateAppearanceWithBlend(annotPtr, annotation.blendMode);
1899
2169
  } else {
1900
2170
  this.pdfiumModule.EPDFAnnot_GenerateAppearance(annotPtr);
@@ -2258,156 +2528,376 @@ class PdfiumNative {
2258
2528
  message: "document does not open"
2259
2529
  });
2260
2530
  }
2261
- const formFillInfoPtr = this.pdfiumModule.PDFiumExt_OpenFormFillInfo();
2262
- const formHandle = this.pdfiumModule.PDFiumExt_InitFormFillEnvironment(
2263
- ctx.docPtr,
2264
- formFillInfoPtr
2265
- );
2266
2531
  const pageCtx = ctx.acquirePage(page.index);
2267
- this.pdfiumModule.FORM_OnAfterLoadPage(pageCtx.pagePtr, formHandle);
2268
- const annotationPtr = this.getAnnotationByName(pageCtx.pagePtr, annotation.id);
2269
- if (!annotationPtr) {
2532
+ try {
2533
+ return pageCtx.withFormHandle((formHandle) => {
2534
+ const annotationPtr = this.getAnnotationByName(pageCtx.pagePtr, annotation.id);
2535
+ if (!annotationPtr) {
2536
+ return PdfTaskHelper.reject({
2537
+ code: PdfErrorCode.NotFound,
2538
+ message: "annotation not found"
2539
+ });
2540
+ }
2541
+ try {
2542
+ if (!this.pdfiumModule.FORM_SetFocusedAnnot(formHandle, annotationPtr)) {
2543
+ return PdfTaskHelper.reject({
2544
+ code: PdfErrorCode.CantFocusAnnot,
2545
+ message: "failed to set focused annotation"
2546
+ });
2547
+ }
2548
+ switch (value.kind) {
2549
+ case "text": {
2550
+ if (!this.pdfiumModule.FORM_SelectAllText(formHandle, pageCtx.pagePtr)) {
2551
+ this.pdfiumModule.FORM_ForceToKillFocus(formHandle);
2552
+ return PdfTaskHelper.reject({
2553
+ code: PdfErrorCode.CantSelectText,
2554
+ message: "failed to select all text"
2555
+ });
2556
+ }
2557
+ const length = 2 * (value.text.length + 1);
2558
+ const textPtr = this.memoryManager.malloc(length);
2559
+ this.pdfiumModule.pdfium.stringToUTF16(value.text, textPtr, length);
2560
+ this.pdfiumModule.FORM_ReplaceSelection(formHandle, pageCtx.pagePtr, textPtr);
2561
+ this.memoryManager.free(textPtr);
2562
+ break;
2563
+ }
2564
+ case "selection": {
2565
+ if (!this.pdfiumModule.FORM_SetIndexSelected(
2566
+ formHandle,
2567
+ pageCtx.pagePtr,
2568
+ value.index,
2569
+ value.isSelected
2570
+ )) {
2571
+ this.pdfiumModule.FORM_ForceToKillFocus(formHandle);
2572
+ return PdfTaskHelper.reject({
2573
+ code: PdfErrorCode.CantSelectOption,
2574
+ message: "failed to set index selected"
2575
+ });
2576
+ }
2577
+ break;
2578
+ }
2579
+ case "checked": {
2580
+ const rawChecked = this.pdfiumModule.FPDFAnnot_IsChecked(formHandle, annotationPtr);
2581
+ const currentlyChecked = !!rawChecked;
2582
+ if (currentlyChecked !== value.checked) {
2583
+ const kReturn = 13;
2584
+ if (!this.pdfiumModule.FORM_OnChar(formHandle, pageCtx.pagePtr, kReturn, 0)) {
2585
+ this.pdfiumModule.FORM_ForceToKillFocus(formHandle);
2586
+ return PdfTaskHelper.reject({
2587
+ code: PdfErrorCode.CantCheckField,
2588
+ message: "failed to set field checked"
2589
+ });
2590
+ }
2591
+ }
2592
+ break;
2593
+ }
2594
+ }
2595
+ this.pdfiumModule.FORM_ForceToKillFocus(formHandle);
2596
+ this.pdfiumModule.EPDFAnnot_GenerateFormFieldAP(annotationPtr);
2597
+ return PdfTaskHelper.resolve(true);
2598
+ } finally {
2599
+ this.pdfiumModule.FPDFPage_CloseAnnot(annotationPtr);
2600
+ }
2601
+ });
2602
+ } finally {
2270
2603
  pageCtx.release();
2604
+ }
2605
+ }
2606
+ /**
2607
+ * {@inheritDoc @embedpdf/models!PdfEngine.setFormFieldState}
2608
+ *
2609
+ * @public
2610
+ */
2611
+ setFormFieldState(doc, page, annotation, field) {
2612
+ this.logger.debug(LOG_SOURCE, LOG_CATEGORY, "SetFormFieldState", doc, annotation, field);
2613
+ this.logger.perf(
2614
+ LOG_SOURCE,
2615
+ LOG_CATEGORY,
2616
+ `SetFormFieldState`,
2617
+ "Begin",
2618
+ `${doc.id}-${annotation.id}`
2619
+ );
2620
+ const ctx = this.cache.getContext(doc.id);
2621
+ if (!ctx) {
2622
+ this.logger.debug(LOG_SOURCE, LOG_CATEGORY, "SetFormFieldState", "document is not opened");
2271
2623
  this.logger.perf(
2272
2624
  LOG_SOURCE,
2273
2625
  LOG_CATEGORY,
2274
- "SetFormFieldValue",
2626
+ `SetFormFieldState`,
2275
2627
  "End",
2276
- `${doc.id}-${page.index}`
2628
+ `${doc.id}-${annotation.id}`
2277
2629
  );
2278
- return PdfTaskHelper.reject({ code: PdfErrorCode.NotFound, message: "annotation not found" });
2630
+ return PdfTaskHelper.reject({
2631
+ code: PdfErrorCode.DocNotOpen,
2632
+ message: "document does not open"
2633
+ });
2279
2634
  }
2280
- if (!this.pdfiumModule.FORM_SetFocusedAnnot(formHandle, annotationPtr)) {
2281
- this.logger.debug(
2282
- LOG_SOURCE,
2283
- LOG_CATEGORY,
2284
- "SetFormFieldValue",
2285
- "failed to set focused annotation"
2286
- );
2635
+ const pageCtx = ctx.acquirePage(page.index);
2636
+ try {
2637
+ return pageCtx.withFormHandle((formHandle) => {
2638
+ const annotationPtr = this.getAnnotationByName(pageCtx.pagePtr, annotation.id);
2639
+ if (!annotationPtr) {
2640
+ return PdfTaskHelper.reject({
2641
+ code: PdfErrorCode.NotFound,
2642
+ message: "annotation not found"
2643
+ });
2644
+ }
2645
+ try {
2646
+ if (!this.pdfiumModule.FORM_SetFocusedAnnot(formHandle, annotationPtr)) {
2647
+ return PdfTaskHelper.reject({
2648
+ code: PdfErrorCode.CantFocusAnnot,
2649
+ message: "failed to set focused annotation"
2650
+ });
2651
+ }
2652
+ switch (field.type) {
2653
+ case PDF_FORM_FIELD_TYPE.TEXTFIELD: {
2654
+ if (!this.pdfiumModule.FORM_SelectAllText(formHandle, pageCtx.pagePtr)) {
2655
+ this.pdfiumModule.FORM_ForceToKillFocus(formHandle);
2656
+ return PdfTaskHelper.reject({
2657
+ code: PdfErrorCode.CantSelectText,
2658
+ message: "failed to select all text"
2659
+ });
2660
+ }
2661
+ const length = 2 * (field.value.length + 1);
2662
+ const textPtr = this.memoryManager.malloc(length);
2663
+ this.pdfiumModule.pdfium.stringToUTF16(field.value, textPtr, length);
2664
+ this.pdfiumModule.FORM_ReplaceSelection(formHandle, pageCtx.pagePtr, textPtr);
2665
+ this.memoryManager.free(textPtr);
2666
+ break;
2667
+ }
2668
+ case PDF_FORM_FIELD_TYPE.CHECKBOX:
2669
+ case PDF_FORM_FIELD_TYPE.RADIOBUTTON: {
2670
+ const currentlyChecked = !!this.pdfiumModule.FPDFAnnot_IsChecked(
2671
+ formHandle,
2672
+ annotationPtr
2673
+ );
2674
+ const desiredChecked = annotation.exportValue != null && field.value === annotation.exportValue;
2675
+ if (currentlyChecked !== desiredChecked) {
2676
+ const kReturn = 13;
2677
+ if (!this.pdfiumModule.FORM_OnChar(formHandle, pageCtx.pagePtr, kReturn, 0)) {
2678
+ this.pdfiumModule.FORM_ForceToKillFocus(formHandle);
2679
+ return PdfTaskHelper.reject({
2680
+ code: PdfErrorCode.CantCheckField,
2681
+ message: "failed to set field checked"
2682
+ });
2683
+ }
2684
+ }
2685
+ break;
2686
+ }
2687
+ case PDF_FORM_FIELD_TYPE.COMBOBOX: {
2688
+ const selectedIndex = field.options.findIndex((opt) => opt.isSelected);
2689
+ if (selectedIndex >= 0) {
2690
+ if (!this.pdfiumModule.FORM_SetIndexSelected(
2691
+ formHandle,
2692
+ pageCtx.pagePtr,
2693
+ selectedIndex,
2694
+ true
2695
+ )) {
2696
+ this.pdfiumModule.FORM_ForceToKillFocus(formHandle);
2697
+ return PdfTaskHelper.reject({
2698
+ code: PdfErrorCode.CantSelectOption,
2699
+ message: "failed to set index selected"
2700
+ });
2701
+ }
2702
+ }
2703
+ break;
2704
+ }
2705
+ case PDF_FORM_FIELD_TYPE.LISTBOX: {
2706
+ for (let i = 0; i < field.options.length; i++) {
2707
+ if (!this.pdfiumModule.FORM_SetIndexSelected(
2708
+ formHandle,
2709
+ pageCtx.pagePtr,
2710
+ i,
2711
+ field.options[i].isSelected
2712
+ )) {
2713
+ this.pdfiumModule.FORM_ForceToKillFocus(formHandle);
2714
+ return PdfTaskHelper.reject({
2715
+ code: PdfErrorCode.CantSelectOption,
2716
+ message: "failed to set index selected"
2717
+ });
2718
+ }
2719
+ }
2720
+ break;
2721
+ }
2722
+ default:
2723
+ break;
2724
+ }
2725
+ this.pdfiumModule.FORM_ForceToKillFocus(formHandle);
2726
+ if (field.type !== PDF_FORM_FIELD_TYPE.CHECKBOX && field.type !== PDF_FORM_FIELD_TYPE.RADIOBUTTON) {
2727
+ this.pdfiumModule.EPDFAnnot_GenerateFormFieldAP(annotationPtr);
2728
+ }
2729
+ this.logger.perf(
2730
+ LOG_SOURCE,
2731
+ LOG_CATEGORY,
2732
+ `SetFormFieldState`,
2733
+ "End",
2734
+ `${doc.id}-${annotation.id}`
2735
+ );
2736
+ return PdfTaskHelper.resolve(true);
2737
+ } finally {
2738
+ this.pdfiumModule.FPDFPage_CloseAnnot(annotationPtr);
2739
+ }
2740
+ });
2741
+ } finally {
2742
+ pageCtx.release();
2743
+ }
2744
+ }
2745
+ renameWidgetField(doc, page, annotation, name) {
2746
+ this.logger.debug(LOG_SOURCE, LOG_CATEGORY, "RenameWidgetField", doc, annotation, name);
2747
+ this.logger.perf(
2748
+ LOG_SOURCE,
2749
+ LOG_CATEGORY,
2750
+ `RenameWidgetField`,
2751
+ "Begin",
2752
+ `${doc.id}-${annotation.id}`
2753
+ );
2754
+ const ctx = this.cache.getContext(doc.id);
2755
+ if (!ctx) {
2287
2756
  this.logger.perf(
2288
2757
  LOG_SOURCE,
2289
2758
  LOG_CATEGORY,
2290
- `SetFormFieldValue`,
2759
+ `RenameWidgetField`,
2291
2760
  "End",
2292
2761
  `${doc.id}-${annotation.id}`
2293
2762
  );
2294
- this.pdfiumModule.FPDFPage_CloseAnnot(annotationPtr);
2295
- this.pdfiumModule.FORM_OnBeforeClosePage(pageCtx.pagePtr, formHandle);
2296
- pageCtx.release();
2297
- this.pdfiumModule.PDFiumExt_ExitFormFillEnvironment(formHandle);
2298
- this.pdfiumModule.PDFiumExt_CloseFormFillInfo(formFillInfoPtr);
2299
2763
  return PdfTaskHelper.reject({
2300
- code: PdfErrorCode.CantFocusAnnot,
2301
- message: "failed to set focused annotation"
2764
+ code: PdfErrorCode.DocNotOpen,
2765
+ message: "document does not open"
2302
2766
  });
2303
2767
  }
2304
- switch (value.kind) {
2305
- case "text":
2306
- {
2307
- if (!this.pdfiumModule.FORM_SelectAllText(formHandle, pageCtx.pagePtr)) {
2308
- this.logger.debug(
2309
- LOG_SOURCE,
2310
- LOG_CATEGORY,
2311
- "SetFormFieldValue",
2312
- "failed to select all text"
2313
- );
2314
- this.logger.perf(
2315
- LOG_SOURCE,
2316
- LOG_CATEGORY,
2317
- `SetFormFieldValue`,
2318
- "End",
2319
- `${doc.id}-${annotation.id}`
2320
- );
2321
- this.pdfiumModule.FORM_ForceToKillFocus(formHandle);
2322
- this.pdfiumModule.FPDFPage_CloseAnnot(annotationPtr);
2323
- this.pdfiumModule.FORM_OnBeforeClosePage(pageCtx.pagePtr, formHandle);
2324
- pageCtx.release();
2325
- this.pdfiumModule.PDFiumExt_ExitFormFillEnvironment(formHandle);
2326
- this.pdfiumModule.PDFiumExt_CloseFormFillInfo(formFillInfoPtr);
2768
+ const pageCtx = ctx.acquirePage(page.index);
2769
+ try {
2770
+ return pageCtx.withFormHandle((formHandle) => {
2771
+ const annotationPtr = this.getAnnotationByName(pageCtx.pagePtr, annotation.id);
2772
+ if (!annotationPtr) {
2773
+ return PdfTaskHelper.reject({
2774
+ code: PdfErrorCode.NotFound,
2775
+ message: "annotation not found"
2776
+ });
2777
+ }
2778
+ try {
2779
+ const ok = this.withWString(
2780
+ name,
2781
+ (namePtr) => this.pdfiumModule.EPDFAnnot_SetFormFieldName(formHandle, annotationPtr, namePtr)
2782
+ );
2783
+ if (!ok) {
2327
2784
  return PdfTaskHelper.reject({
2328
- code: PdfErrorCode.CantSelectText,
2329
- message: "failed to select all text"
2785
+ code: PdfErrorCode.CantSetAnnotString,
2786
+ message: "failed to rename widget field"
2330
2787
  });
2331
2788
  }
2332
- const length = 2 * (value.text.length + 1);
2333
- const textPtr = this.memoryManager.malloc(length);
2334
- this.pdfiumModule.pdfium.stringToUTF16(value.text, textPtr, length);
2335
- this.pdfiumModule.FORM_ReplaceSelection(formHandle, pageCtx.pagePtr, textPtr);
2336
- this.memoryManager.free(textPtr);
2789
+ this.logger.perf(
2790
+ LOG_SOURCE,
2791
+ LOG_CATEGORY,
2792
+ `RenameWidgetField`,
2793
+ "End",
2794
+ `${doc.id}-${annotation.id}`
2795
+ );
2796
+ return PdfTaskHelper.resolve(true);
2797
+ } finally {
2798
+ this.pdfiumModule.FPDFPage_CloseAnnot(annotationPtr);
2337
2799
  }
2338
- break;
2339
- case "selection":
2340
- {
2341
- if (!this.pdfiumModule.FORM_SetIndexSelected(
2342
- formHandle,
2343
- pageCtx.pagePtr,
2344
- value.index,
2345
- value.isSelected
2346
- )) {
2347
- this.logger.debug(
2348
- LOG_SOURCE,
2349
- LOG_CATEGORY,
2350
- "SetFormFieldValue",
2351
- "failed to set index selected"
2352
- );
2353
- this.logger.perf(
2354
- LOG_SOURCE,
2355
- LOG_CATEGORY,
2356
- `SetFormFieldValue`,
2357
- "End",
2358
- `${doc.id}-${annotation.id}`
2359
- );
2360
- this.pdfiumModule.FORM_ForceToKillFocus(formHandle);
2361
- this.pdfiumModule.FPDFPage_CloseAnnot(annotationPtr);
2362
- this.pdfiumModule.FORM_OnBeforeClosePage(pageCtx.pagePtr, formHandle);
2363
- pageCtx.release();
2364
- this.pdfiumModule.PDFiumExt_ExitFormFillEnvironment(formHandle);
2365
- this.pdfiumModule.PDFiumExt_CloseFormFillInfo(formFillInfoPtr);
2366
- return PdfTaskHelper.reject({
2367
- code: PdfErrorCode.CantSelectOption,
2368
- message: "failed to set index selected"
2369
- });
2800
+ });
2801
+ } finally {
2802
+ pageCtx.release();
2803
+ }
2804
+ }
2805
+ shareWidgetField(doc, sourcePage, sourceAnnotation, targetPage, targetAnnotation) {
2806
+ this.logger.debug(
2807
+ LOG_SOURCE,
2808
+ LOG_CATEGORY,
2809
+ "ShareWidgetField",
2810
+ doc,
2811
+ sourceAnnotation,
2812
+ targetAnnotation
2813
+ );
2814
+ this.logger.perf(
2815
+ LOG_SOURCE,
2816
+ LOG_CATEGORY,
2817
+ `ShareWidgetField`,
2818
+ "Begin",
2819
+ `${doc.id}-${sourceAnnotation.id}-${targetAnnotation.id}`
2820
+ );
2821
+ const ctx = this.cache.getContext(doc.id);
2822
+ if (!ctx) {
2823
+ this.logger.perf(
2824
+ LOG_SOURCE,
2825
+ LOG_CATEGORY,
2826
+ `ShareWidgetField`,
2827
+ "End",
2828
+ `${doc.id}-${sourceAnnotation.id}-${targetAnnotation.id}`
2829
+ );
2830
+ return PdfTaskHelper.reject({
2831
+ code: PdfErrorCode.DocNotOpen,
2832
+ message: "document does not open"
2833
+ });
2834
+ }
2835
+ const sourcePageCtx = ctx.acquirePage(sourcePage.index);
2836
+ const targetPageCtx = targetPage.index === sourcePage.index ? sourcePageCtx : ctx.acquirePage(targetPage.index);
2837
+ try {
2838
+ return sourcePageCtx.withFormHandle((formHandle) => {
2839
+ let targetPageLoaded = false;
2840
+ if (targetPageCtx !== sourcePageCtx) {
2841
+ this.pdfiumModule.FORM_OnAfterLoadPage(targetPageCtx.pagePtr, formHandle);
2842
+ targetPageLoaded = true;
2843
+ }
2844
+ const sourceAnnotationPtr = this.getAnnotationByName(
2845
+ sourcePageCtx.pagePtr,
2846
+ sourceAnnotation.id
2847
+ );
2848
+ const targetAnnotationPtr = this.getAnnotationByName(
2849
+ targetPageCtx.pagePtr,
2850
+ targetAnnotation.id
2851
+ );
2852
+ if (!sourceAnnotationPtr || !targetAnnotationPtr) {
2853
+ if (sourceAnnotationPtr) {
2854
+ this.pdfiumModule.FPDFPage_CloseAnnot(sourceAnnotationPtr);
2370
2855
  }
2856
+ if (targetAnnotationPtr) {
2857
+ this.pdfiumModule.FPDFPage_CloseAnnot(targetAnnotationPtr);
2858
+ }
2859
+ if (targetPageLoaded) {
2860
+ this.pdfiumModule.FORM_OnBeforeClosePage(targetPageCtx.pagePtr, formHandle);
2861
+ }
2862
+ return PdfTaskHelper.reject({
2863
+ code: PdfErrorCode.NotFound,
2864
+ message: "annotation not found"
2865
+ });
2371
2866
  }
2372
- break;
2373
- case "checked":
2374
- {
2375
- const kReturn = 13;
2376
- if (!this.pdfiumModule.FORM_OnChar(formHandle, pageCtx.pagePtr, kReturn, 0)) {
2377
- this.logger.debug(
2378
- LOG_SOURCE,
2379
- LOG_CATEGORY,
2380
- "SetFormFieldValue",
2381
- "failed to set field checked"
2382
- );
2383
- this.logger.perf(
2384
- LOG_SOURCE,
2385
- LOG_CATEGORY,
2386
- `SetFormFieldValue`,
2387
- "End",
2388
- `${doc.id}-${annotation.id}`
2389
- );
2390
- this.pdfiumModule.FORM_ForceToKillFocus(formHandle);
2391
- this.pdfiumModule.FPDFPage_CloseAnnot(annotationPtr);
2392
- this.pdfiumModule.FORM_OnBeforeClosePage(pageCtx.pagePtr, formHandle);
2393
- pageCtx.release();
2394
- this.pdfiumModule.PDFiumExt_ExitFormFillEnvironment(formHandle);
2395
- this.pdfiumModule.PDFiumExt_CloseFormFillInfo(formFillInfoPtr);
2867
+ try {
2868
+ const ok = this.pdfiumModule.EPDFAnnot_ShareFormField(
2869
+ formHandle,
2870
+ sourceAnnotationPtr,
2871
+ targetAnnotationPtr
2872
+ );
2873
+ if (!ok) {
2396
2874
  return PdfTaskHelper.reject({
2397
- code: PdfErrorCode.CantCheckField,
2398
- message: "failed to set field checked"
2875
+ code: PdfErrorCode.Unknown,
2876
+ message: "failed to share widget field"
2399
2877
  });
2400
2878
  }
2879
+ this.logger.perf(
2880
+ LOG_SOURCE,
2881
+ LOG_CATEGORY,
2882
+ `ShareWidgetField`,
2883
+ "End",
2884
+ `${doc.id}-${sourceAnnotation.id}-${targetAnnotation.id}`
2885
+ );
2886
+ return PdfTaskHelper.resolve(true);
2887
+ } finally {
2888
+ this.pdfiumModule.FPDFPage_CloseAnnot(sourceAnnotationPtr);
2889
+ this.pdfiumModule.FPDFPage_CloseAnnot(targetAnnotationPtr);
2890
+ if (targetPageLoaded) {
2891
+ this.pdfiumModule.FORM_OnBeforeClosePage(targetPageCtx.pagePtr, formHandle);
2892
+ }
2401
2893
  }
2402
- break;
2894
+ });
2895
+ } finally {
2896
+ sourcePageCtx.release();
2897
+ if (targetPageCtx !== sourcePageCtx) {
2898
+ targetPageCtx.release();
2899
+ }
2403
2900
  }
2404
- this.pdfiumModule.FORM_ForceToKillFocus(formHandle);
2405
- this.pdfiumModule.FPDFPage_CloseAnnot(annotationPtr);
2406
- this.pdfiumModule.FORM_OnBeforeClosePage(pageCtx.pagePtr, formHandle);
2407
- pageCtx.release();
2408
- this.pdfiumModule.PDFiumExt_ExitFormFillEnvironment(formHandle);
2409
- this.pdfiumModule.PDFiumExt_CloseFormFillInfo(formFillInfoPtr);
2410
- return PdfTaskHelper.resolve(true);
2411
2901
  }
2412
2902
  /**
2413
2903
  * {@inheritDoc @embedpdf/models!PdfEngine.flattenPage}
@@ -2943,7 +3433,7 @@ class PdfiumNative {
2943
3433
  }
2944
3434
  if (!this.setAnnotationDefaultAppearance(
2945
3435
  annotationPtr,
2946
- annotation.fontFamily,
3436
+ annotation.fontFamily === PdfStandardFont.Unknown ? PdfStandardFont.Helvetica : annotation.fontFamily,
2947
3437
  annotation.fontSize,
2948
3438
  annotation.fontColor
2949
3439
  )) {
@@ -2963,6 +3453,184 @@ class PdfiumNative {
2963
3453
  this.setRectangleDifferences(annotationPtr, annotation.rectangleDifferences);
2964
3454
  return this.applyBaseAnnotationProperties(doc, page, pagePtr, annotationPtr, annotation);
2965
3455
  }
3456
+ addTextFieldContent(formHandle, annotationPtr, annotation) {
3457
+ if (!this.setAnnotationDefaultAppearance(
3458
+ annotationPtr,
3459
+ annotation.fontFamily,
3460
+ annotation.fontSize,
3461
+ annotation.fontColor
3462
+ )) {
3463
+ return false;
3464
+ }
3465
+ if (!this.setBorderStyle(
3466
+ annotationPtr,
3467
+ PdfAnnotationBorderStyle.SOLID,
3468
+ annotation.strokeWidth ?? 1
3469
+ )) {
3470
+ return false;
3471
+ }
3472
+ if (annotation.strokeColor && annotation.strokeColor !== "transparent") {
3473
+ this.setMKColor(annotationPtr, 0, annotation.strokeColor);
3474
+ } else {
3475
+ this.clearMKColor(annotationPtr, 0);
3476
+ }
3477
+ if (annotation.color && annotation.color !== "transparent") {
3478
+ this.setMKColor(annotationPtr, 1, annotation.color);
3479
+ } else {
3480
+ this.clearMKColor(annotationPtr, 1);
3481
+ }
3482
+ const userFlags = annotation.field.flag ?? PDF_FORM_FIELD_FLAG.NONE;
3483
+ this.pdfiumModule.FPDFAnnot_SetFormFieldFlags(formHandle, annotationPtr, userFlags);
3484
+ if (annotation.field.name) {
3485
+ this.withWString(
3486
+ annotation.field.name,
3487
+ (namePtr) => this.pdfiumModule.EPDFAnnot_SetFormFieldName(formHandle, annotationPtr, namePtr)
3488
+ );
3489
+ }
3490
+ this.withWString(
3491
+ annotation.field.value ?? "",
3492
+ (valuePtr) => this.pdfiumModule.EPDFAnnot_SetFormFieldValue(formHandle, annotationPtr, valuePtr)
3493
+ );
3494
+ const textField = annotation.field;
3495
+ if (textField.maxLen != null && textField.maxLen > 0) {
3496
+ this.pdfiumModule.EPDFAnnot_SetNumberValue(annotationPtr, "MaxLen", textField.maxLen);
3497
+ }
3498
+ return true;
3499
+ }
3500
+ addToggleFieldContent(formHandle, annotationPtr, annotation) {
3501
+ if (!this.setBorderStyle(
3502
+ annotationPtr,
3503
+ PdfAnnotationBorderStyle.SOLID,
3504
+ annotation.strokeWidth ?? 1
3505
+ )) {
3506
+ return false;
3507
+ }
3508
+ if (annotation.strokeColor && annotation.strokeColor !== "transparent") {
3509
+ this.setMKColor(annotationPtr, 0, annotation.strokeColor);
3510
+ } else {
3511
+ this.clearMKColor(annotationPtr, 0);
3512
+ }
3513
+ if (annotation.color && annotation.color !== "transparent") {
3514
+ this.setMKColor(annotationPtr, 1, annotation.color);
3515
+ } else {
3516
+ this.clearMKColor(annotationPtr, 1);
3517
+ }
3518
+ let finalFlags = annotation.field.flag ?? PDF_FORM_FIELD_FLAG.NONE;
3519
+ if (annotation.field.type === PDF_FORM_FIELD_TYPE.RADIOBUTTON) {
3520
+ finalFlags |= PDF_FORM_FIELD_FLAG.BUTTON_RADIO | PDF_FORM_FIELD_FLAG.BUTTON_NOTOGGLETOOFF;
3521
+ }
3522
+ this.pdfiumModule.FPDFAnnot_SetFormFieldFlags(formHandle, annotationPtr, finalFlags);
3523
+ if (annotation.field.name) {
3524
+ this.withWString(
3525
+ annotation.field.name,
3526
+ (namePtr) => this.pdfiumModule.EPDFAnnot_SetFormFieldName(formHandle, annotationPtr, namePtr)
3527
+ );
3528
+ }
3529
+ return true;
3530
+ }
3531
+ addChoiceFieldContent(formHandle, annotationPtr, annotation) {
3532
+ if (!this.setAnnotationDefaultAppearance(
3533
+ annotationPtr,
3534
+ annotation.fontFamily,
3535
+ annotation.fontSize,
3536
+ annotation.fontColor
3537
+ )) {
3538
+ return false;
3539
+ }
3540
+ if (!this.setBorderStyle(
3541
+ annotationPtr,
3542
+ PdfAnnotationBorderStyle.SOLID,
3543
+ annotation.strokeWidth ?? 1
3544
+ )) {
3545
+ return false;
3546
+ }
3547
+ if (annotation.strokeColor && annotation.strokeColor !== "transparent") {
3548
+ this.setMKColor(annotationPtr, 0, annotation.strokeColor);
3549
+ } else {
3550
+ this.clearMKColor(annotationPtr, 0);
3551
+ }
3552
+ if (annotation.color && annotation.color !== "transparent") {
3553
+ this.setMKColor(annotationPtr, 1, annotation.color);
3554
+ } else {
3555
+ this.clearMKColor(annotationPtr, 1);
3556
+ }
3557
+ let choiceFlags = annotation.field.flag ?? PDF_FORM_FIELD_FLAG.NONE;
3558
+ if (annotation.field.type === PDF_FORM_FIELD_TYPE.COMBOBOX) {
3559
+ choiceFlags |= 1 << 17;
3560
+ }
3561
+ this.pdfiumModule.FPDFAnnot_SetFormFieldFlags(formHandle, annotationPtr, choiceFlags);
3562
+ if (annotation.field.name) {
3563
+ this.withWString(
3564
+ annotation.field.name,
3565
+ (namePtr) => this.pdfiumModule.EPDFAnnot_SetFormFieldName(formHandle, annotationPtr, namePtr)
3566
+ );
3567
+ }
3568
+ const field = annotation.field;
3569
+ const options = field.options ?? [];
3570
+ if (options.length > 0) {
3571
+ const ptrSize = 4;
3572
+ const arrayPtr = this.memoryManager.malloc(options.length * ptrSize);
3573
+ const labelPtrs = [];
3574
+ try {
3575
+ for (let i = 0; i < options.length; i++) {
3576
+ const label = options[i].label;
3577
+ const byteLen = (label.length + 1) * 2;
3578
+ const labelPtr = this.memoryManager.malloc(byteLen);
3579
+ this.pdfiumModule.pdfium.stringToUTF16(label, labelPtr, byteLen);
3580
+ labelPtrs.push(labelPtr);
3581
+ this.pdfiumModule.pdfium.setValue(arrayPtr + i * ptrSize, labelPtr, "*");
3582
+ }
3583
+ this.pdfiumModule.EPDFAnnot_SetFormFieldOptions(
3584
+ formHandle,
3585
+ annotationPtr,
3586
+ arrayPtr,
3587
+ options.length
3588
+ );
3589
+ } finally {
3590
+ for (const ptr of labelPtrs) {
3591
+ this.memoryManager.free(WasmPointer(ptr));
3592
+ }
3593
+ this.memoryManager.free(arrayPtr);
3594
+ }
3595
+ }
3596
+ const selectedOption = options.find((opt) => opt.isSelected);
3597
+ const value = (selectedOption == null ? void 0 : selectedOption.label) ?? annotation.field.value ?? "";
3598
+ this.withWString(
3599
+ value,
3600
+ (valuePtr) => this.pdfiumModule.EPDFAnnot_SetFormFieldValue(formHandle, annotationPtr, valuePtr)
3601
+ );
3602
+ return true;
3603
+ }
3604
+ setMKColor(annotationPtr, mkType, webColor) {
3605
+ const { red, green, blue } = webColorToPdfColor(webColor);
3606
+ return this.pdfiumModule.EPDFAnnot_SetMKColor(
3607
+ annotationPtr,
3608
+ mkType,
3609
+ red & 255,
3610
+ green & 255,
3611
+ blue & 255
3612
+ );
3613
+ }
3614
+ clearMKColor(annotationPtr, mkType) {
3615
+ return this.pdfiumModule.EPDFAnnot_ClearMKColor(annotationPtr, mkType);
3616
+ }
3617
+ getMKColor(annotationPtr, mkType) {
3618
+ const rPtr = this.memoryManager.malloc(4);
3619
+ const gPtr = this.memoryManager.malloc(4);
3620
+ const bPtr = this.memoryManager.malloc(4);
3621
+ try {
3622
+ const ok = this.pdfiumModule.EPDFAnnot_GetMKColor(annotationPtr, mkType, rPtr, gPtr, bPtr);
3623
+ if (!ok) return void 0;
3624
+ const r = this.pdfiumModule.pdfium.getValue(rPtr, "i32") & 255;
3625
+ const g = this.pdfiumModule.pdfium.getValue(gPtr, "i32") & 255;
3626
+ const b = this.pdfiumModule.pdfium.getValue(bPtr, "i32") & 255;
3627
+ return pdfColorToWebColor({ red: r, green: g, blue: b });
3628
+ } finally {
3629
+ this.memoryManager.free(bPtr);
3630
+ this.memoryManager.free(gPtr);
3631
+ this.memoryManager.free(rPtr);
3632
+ }
3633
+ }
2966
3634
  /**
2967
3635
  * Set the rect of specified annotation
2968
3636
  * @param page - page info that the annotation is belonged to
@@ -3260,9 +3928,10 @@ class PdfiumNative {
3260
3928
  return false;
3261
3929
  }
3262
3930
  if (annotation.fontFamily !== void 0 || annotation.fontSize !== void 0) {
3931
+ const font = annotation.fontFamily == null || annotation.fontFamily === PdfStandardFont.Unknown ? PdfStandardFont.Helvetica : annotation.fontFamily;
3263
3932
  if (!this.setAnnotationDefaultAppearance(
3264
3933
  annotationPtr,
3265
- annotation.fontFamily ?? PdfStandardFont.Helvetica,
3934
+ font,
3266
3935
  annotation.fontSize ?? 12,
3267
3936
  annotation.fontColor ?? "#000000"
3268
3937
  )) {
@@ -4254,18 +4923,45 @@ class PdfiumNative {
4254
4923
  */
4255
4924
  readPageAnnotations(doc, ctx, page) {
4256
4925
  return ctx.borrowPage(page.index, (pageCtx) => {
4257
- const annotationCount = this.pdfiumModule.FPDFPage_GetAnnotCount(pageCtx.pagePtr);
4258
- const annotations = [];
4259
- for (let i = 0; i < annotationCount; i++) {
4260
- pageCtx.withAnnotation(i, (annotPtr) => {
4261
- const anno = this.readPageAnnotation(doc, ctx.docPtr, page, annotPtr, pageCtx);
4262
- if (anno) annotations.push(anno);
4263
- });
4264
- }
4265
- return annotations;
4926
+ return pageCtx.withFormHandle((formHandle) => {
4927
+ const annotationCount = this.pdfiumModule.FPDFPage_GetAnnotCount(pageCtx.pagePtr);
4928
+ const annotations = [];
4929
+ for (let i = 0; i < annotationCount; i++) {
4930
+ pageCtx.withAnnotation(i, (annotPtr) => {
4931
+ const anno = this.readPageAnnotation(doc, ctx.docPtr, page, annotPtr, formHandle);
4932
+ if (anno) annotations.push(anno);
4933
+ });
4934
+ }
4935
+ return annotations;
4936
+ });
4266
4937
  });
4267
4938
  }
4268
4939
  /**
4940
+ *
4941
+ *
4942
+ * @param ctx - document context
4943
+ * @param page - page info
4944
+ * @returns form fields on the pdf page
4945
+ *
4946
+ * @private
4947
+ */
4948
+ readPageAnnoWidgets(doc, ctx, page) {
4949
+ return ctx.borrowPage(page.index, (pageCtx) => {
4950
+ return pageCtx.withFormHandle((formHandle) => {
4951
+ const annotationCount = this.pdfiumModule.FPDFPage_GetAnnotCount(pageCtx.pagePtr);
4952
+ const annotations = [];
4953
+ for (let i = 0; i < annotationCount; i++) {
4954
+ pageCtx.withAnnotation(i, (annotPtr) => {
4955
+ const anno = this.readPageAnnoWidget(doc, page, annotPtr, formHandle);
4956
+ if (anno) annotations.push(anno);
4957
+ });
4958
+ }
4959
+ return annotations;
4960
+ });
4961
+ });
4962
+ }
4963
+ /**
4964
+ * Read page annotations
4269
4965
  * Read page annotations without loading the page (raw approach)
4270
4966
  *
4271
4967
  * @param doc - pdf document object
@@ -4275,7 +4971,7 @@ class PdfiumNative {
4275
4971
  *
4276
4972
  * @private
4277
4973
  */
4278
- readPageAnnotationsRaw(doc, ctx, page) {
4974
+ readPageAnnotationsRaw(doc, ctx, page, formHandle) {
4279
4975
  const count = this.pdfiumModule.EPDFPage_GetAnnotCountRaw(ctx.docPtr, page.index);
4280
4976
  if (count <= 0) return [];
4281
4977
  const out = [];
@@ -4283,7 +4979,7 @@ class PdfiumNative {
4283
4979
  const annotPtr = this.pdfiumModule.EPDFPage_GetAnnotRaw(ctx.docPtr, page.index, i);
4284
4980
  if (!annotPtr) continue;
4285
4981
  try {
4286
- const anno = this.readPageAnnotation(doc, ctx.docPtr, page, annotPtr);
4982
+ const anno = this.readPageAnnotation(doc, ctx.docPtr, page, annotPtr, formHandle);
4287
4983
  if (anno) out.push(anno);
4288
4984
  } finally {
4289
4985
  this.pdfiumModule.FPDFPage_CloseAnnot(annotPtr);
@@ -4292,6 +4988,29 @@ class PdfiumNative {
4292
4988
  return out;
4293
4989
  }
4294
4990
  /**
4991
+ * Read page form field
4992
+ *
4993
+ * @param ctx - document context
4994
+ * @param page - page info
4995
+ * @param annotationPtr - pointer to pdf annotation
4996
+ * @param pageCtx - page context
4997
+ * @returns form field
4998
+ *
4999
+ * @private
5000
+ */
5001
+ readPageAnnoWidget(doc, page, annotationPtr, formHandle) {
5002
+ let index = this.getAnnotString(annotationPtr, "NM");
5003
+ if (!index || !isUuidV4(index)) {
5004
+ index = uuidV4();
5005
+ this.setAnnotString(annotationPtr, "NM", index);
5006
+ }
5007
+ const subType = this.pdfiumModule.FPDFAnnot_GetSubtype(
5008
+ annotationPtr
5009
+ );
5010
+ if (subType !== PdfAnnotationSubtype.WIDGET) return;
5011
+ return this.readPdfWidgetAnno(doc, page, annotationPtr, formHandle, index);
5012
+ }
5013
+ /*
4295
5014
  * Get page annotations (public API, returns Task)
4296
5015
  *
4297
5016
  * @param doc - pdf document
@@ -4316,22 +5035,29 @@ class PdfiumNative {
4316
5035
  message: "document does not open"
4317
5036
  });
4318
5037
  }
4319
- const out = this.readPageAnnotationsRaw(doc, ctx, page);
4320
- this.logger.perf(
4321
- LOG_SOURCE,
4322
- LOG_CATEGORY,
4323
- `GetPageAnnotationsRaw`,
4324
- "End",
4325
- `${doc.id}-${page.index}`
4326
- );
4327
- this.logger.debug(
4328
- LOG_SOURCE,
4329
- LOG_CATEGORY,
4330
- "getPageAnnotationsRaw",
4331
- `${doc.id}-${page.index}`,
4332
- out
4333
- );
4334
- return PdfTaskHelper.resolve(out);
5038
+ const formInfoPtr = this.pdfiumModule.PDFiumExt_OpenFormFillInfo();
5039
+ const formHandle = this.pdfiumModule.PDFiumExt_InitFormFillEnvironment(ctx.docPtr, formInfoPtr);
5040
+ try {
5041
+ const out = this.readPageAnnotationsRaw(doc, ctx, page, formHandle);
5042
+ this.logger.perf(
5043
+ LOG_SOURCE,
5044
+ LOG_CATEGORY,
5045
+ `GetPageAnnotationsRaw`,
5046
+ "End",
5047
+ `${doc.id}-${page.index}`
5048
+ );
5049
+ this.logger.debug(
5050
+ LOG_SOURCE,
5051
+ LOG_CATEGORY,
5052
+ "getPageAnnotationsRaw",
5053
+ `${doc.id}-${page.index}`,
5054
+ out
5055
+ );
5056
+ return PdfTaskHelper.resolve(out);
5057
+ } finally {
5058
+ this.pdfiumModule.PDFiumExt_ExitFormFillEnvironment(formHandle);
5059
+ this.pdfiumModule.PDFiumExt_CloseFormFillInfo(formInfoPtr);
5060
+ }
4335
5061
  }
4336
5062
  /**
4337
5063
  * Read pdf annotation from pdf document
@@ -4340,12 +5066,12 @@ class PdfiumNative {
4340
5066
  * @param docPtr - pointer to pdf document
4341
5067
  * @param page - page info
4342
5068
  * @param annotationPtr - pointer to pdf annotation
4343
- * @param pageCtx - page context
5069
+ * @param formHandle - optional form fill handle for widget annotations
4344
5070
  * @returns pdf annotation
4345
5071
  *
4346
5072
  * @private
4347
5073
  */
4348
- readPageAnnotation(doc, docPtr, page, annotationPtr, pageCtx) {
5074
+ readPageAnnotation(doc, docPtr, page, annotationPtr, formHandle) {
4349
5075
  let index = this.getAnnotString(annotationPtr, "NM");
4350
5076
  if (!index || !isUuidV4(index)) {
4351
5077
  index = uuidV4();
@@ -4372,9 +5098,12 @@ class PdfiumNative {
4372
5098
  }
4373
5099
  break;
4374
5100
  case PdfAnnotationSubtype.WIDGET:
4375
- if (pageCtx) {
4376
- return this.readPdfWidgetAnno(doc, page, annotationPtr, pageCtx.getFormHandle(), index);
5101
+ {
5102
+ if (formHandle !== void 0) {
5103
+ return this.readPdfWidgetAnno(doc, page, annotationPtr, formHandle, index);
5104
+ }
4377
5105
  }
5106
+ break;
4378
5107
  case PdfAnnotationSubtype.FILEATTACHMENT:
4379
5108
  {
4380
5109
  annotation = this.readPdfFileAttachmentAnno(doc, page, annotationPtr, index);
@@ -4696,10 +5425,10 @@ class PdfiumNative {
4696
5425
  * @returns true on success
4697
5426
  */
4698
5427
  setAnnotUnrotatedRect(doc, page, annotPtr, rect) {
4699
- const x0d = Math.floor(rect.origin.x);
4700
- const y0d = Math.floor(rect.origin.y);
4701
- const x1d = Math.floor(rect.origin.x + rect.size.width);
4702
- const y1d = Math.floor(rect.origin.y + rect.size.height);
5428
+ const x0d = rect.origin.x;
5429
+ const y0d = rect.origin.y;
5430
+ const x1d = rect.origin.x + rect.size.width;
5431
+ const y1d = rect.origin.y + rect.size.height;
4703
5432
  const TL = this.convertDevicePointToPagePoint(doc, page, { x: x0d, y: y0d });
4704
5433
  const TR = this.convertDevicePointToPagePoint(doc, page, { x: x1d, y: y0d });
4705
5434
  const BR = this.convertDevicePointToPagePoint(doc, page, { x: x1d, y: y1d });
@@ -4869,11 +5598,10 @@ class PdfiumNative {
4869
5598
  * @returns `true` on success
4870
5599
  */
4871
5600
  setAnnotationDefaultAppearance(annotationPtr, font, fontSize, color) {
4872
- const resolvedFont = font === PdfStandardFont.Unknown ? PdfStandardFont.Helvetica : font;
4873
5601
  const { red, green, blue } = webColorToPdfColor(color);
4874
5602
  return !!this.pdfiumModule.EPDFAnnot_SetDefaultAppearance(
4875
5603
  annotationPtr,
4876
- resolvedFont,
5604
+ font,
4877
5605
  fontSize,
4878
5606
  red & 255,
4879
5607
  green & 255,
@@ -5724,14 +6452,27 @@ class PdfiumNative {
5724
6452
  */
5725
6453
  readPdfWidgetAnno(doc, page, annotationPtr, formHandle, index) {
5726
6454
  const pageRect = this.readPageAnnoRect(annotationPtr);
6455
+ this.getAnnotationFlags(annotationPtr);
6456
+ const da = this.getAnnotationDefaultAppearance(annotationPtr);
5727
6457
  const rect = this.convertPageRectToDeviceRect(doc, page, pageRect);
5728
6458
  const field = this.readPdfWidgetAnnoField(formHandle, annotationPtr);
6459
+ const exportValue = this.readButtonExportValue(annotationPtr);
6460
+ const strokeColor = this.getMKColor(annotationPtr, 0);
6461
+ const color = this.getMKColor(annotationPtr, 1);
6462
+ const { width: strokeWidth } = this.getBorderStyle(annotationPtr);
5729
6463
  return {
5730
6464
  pageIndex: page.index,
5731
6465
  id: index,
5732
6466
  type: PdfAnnotationSubtype.WIDGET,
6467
+ fontFamily: (da == null ? void 0 : da.fontFamily) ?? PdfStandardFont.Unknown,
6468
+ fontSize: (da == null ? void 0 : da.fontSize) ?? 12,
6469
+ fontColor: (da == null ? void 0 : da.fontColor) ?? "#000000",
5733
6470
  rect,
5734
6471
  field,
6472
+ ...exportValue !== void 0 && { exportValue },
6473
+ strokeWidth,
6474
+ strokeColor: strokeColor ?? "transparent",
6475
+ color: color ?? "transparent",
5735
6476
  ...this.readBaseAnnotationProperties(doc, page, annotationPtr)
5736
6477
  };
5737
6478
  }
@@ -6717,6 +7458,16 @@ class PdfiumNative {
6717
7458
  this.memoryManager.free(ptr);
6718
7459
  return value || void 0;
6719
7460
  }
7461
+ readButtonExportValue(annotationPtr) {
7462
+ const len = this.pdfiumModule.EPDFAnnot_GetButtonExportValue(annotationPtr, 0, 0);
7463
+ if (len === 0) return;
7464
+ const bytes = (len + 1) * 2;
7465
+ const ptr = this.memoryManager.malloc(bytes);
7466
+ this.pdfiumModule.EPDFAnnot_GetButtonExportValue(annotationPtr, ptr, bytes);
7467
+ const value = this.pdfiumModule.pdfium.UTF16ToString(ptr);
7468
+ this.memoryManager.free(ptr);
7469
+ return value || void 0;
7470
+ }
6720
7471
  /**
6721
7472
  * Get a string value (`/T`, `/M`, `/State`, …) from an attachment.
6722
7473
  *
@@ -7017,7 +7768,7 @@ class PdfiumNative {
7017
7768
  const value = readString(
7018
7769
  this.pdfiumModule.pdfium,
7019
7770
  (buffer, bufferLength) => {
7020
- return this.pdfiumModule.FPDFAnnot_GetFormFieldValue(
7771
+ return this.pdfiumModule.EPDFAnnot_GetFormFieldRawValue(
7021
7772
  formHandle,
7022
7773
  annotationPtr,
7023
7774
  buffer,
@@ -7026,47 +7777,69 @@ class PdfiumNative {
7026
7777
  },
7027
7778
  this.pdfiumModule.pdfium.UTF16ToString
7028
7779
  );
7029
- const options = [];
7030
- if (type === PDF_FORM_FIELD_TYPE.COMBOBOX || type === PDF_FORM_FIELD_TYPE.LISTBOX) {
7031
- const count = this.pdfiumModule.FPDFAnnot_GetOptionCount(formHandle, annotationPtr);
7032
- for (let i = 0; i < count; i++) {
7033
- const label = readString(
7034
- this.pdfiumModule.pdfium,
7035
- (buffer, bufferLength) => {
7036
- return this.pdfiumModule.FPDFAnnot_GetOptionLabel(
7037
- formHandle,
7038
- annotationPtr,
7039
- i,
7040
- buffer,
7041
- bufferLength
7042
- );
7043
- },
7044
- this.pdfiumModule.pdfium.UTF16ToString
7045
- );
7046
- const isSelected = this.pdfiumModule.FPDFAnnot_IsOptionSelected(
7047
- formHandle,
7048
- annotationPtr,
7049
- i
7050
- );
7051
- options.push({
7052
- label,
7053
- isSelected
7054
- });
7055
- }
7056
- }
7057
- let isChecked = false;
7058
- if (type === PDF_FORM_FIELD_TYPE.CHECKBOX || type === PDF_FORM_FIELD_TYPE.RADIOBUTTON) {
7059
- isChecked = this.pdfiumModule.FPDFAnnot_IsChecked(formHandle, annotationPtr);
7060
- }
7061
- return {
7780
+ const fieldObjectId = this.pdfiumModule.EPDFAnnot_GetFormFieldObjectNumber(
7781
+ formHandle,
7782
+ annotationPtr
7783
+ );
7784
+ const base = {
7062
7785
  flag,
7063
- type,
7064
7786
  name,
7065
7787
  alternateName,
7066
7788
  value,
7067
- isChecked,
7068
- options
7789
+ fieldObjectId: fieldObjectId > 0 ? fieldObjectId : void 0
7069
7790
  };
7791
+ switch (type) {
7792
+ case PDF_FORM_FIELD_TYPE.TEXTFIELD: {
7793
+ let maxLen;
7794
+ const floatPtr = this.memoryManager.malloc(4);
7795
+ const ok = this.pdfiumModule.FPDFAnnot_GetNumberValue(annotationPtr, "MaxLen", floatPtr);
7796
+ if (ok) {
7797
+ maxLen = this.pdfiumModule.pdfium.getValue(floatPtr, "float");
7798
+ }
7799
+ this.memoryManager.free(floatPtr);
7800
+ return { ...base, type, maxLen };
7801
+ }
7802
+ case PDF_FORM_FIELD_TYPE.CHECKBOX:
7803
+ return { ...base, type };
7804
+ case PDF_FORM_FIELD_TYPE.RADIOBUTTON:
7805
+ return {
7806
+ ...base,
7807
+ type,
7808
+ options: this.readWidgetOptions(formHandle, annotationPtr)
7809
+ };
7810
+ case PDF_FORM_FIELD_TYPE.COMBOBOX:
7811
+ return { ...base, type, options: this.readWidgetOptions(formHandle, annotationPtr) };
7812
+ case PDF_FORM_FIELD_TYPE.LISTBOX:
7813
+ return { ...base, type, options: this.readWidgetOptions(formHandle, annotationPtr) };
7814
+ case PDF_FORM_FIELD_TYPE.PUSHBUTTON:
7815
+ return { ...base, type };
7816
+ case PDF_FORM_FIELD_TYPE.SIGNATURE:
7817
+ return { ...base, type };
7818
+ default:
7819
+ return { ...base, type };
7820
+ }
7821
+ }
7822
+ readWidgetOptions(formHandle, annotationPtr) {
7823
+ const options = [];
7824
+ const count = this.pdfiumModule.FPDFAnnot_GetOptionCount(formHandle, annotationPtr);
7825
+ for (let i = 0; i < count; i++) {
7826
+ const label = readString(
7827
+ this.pdfiumModule.pdfium,
7828
+ (buffer, bufferLength) => {
7829
+ return this.pdfiumModule.FPDFAnnot_GetOptionLabel(
7830
+ formHandle,
7831
+ annotationPtr,
7832
+ i,
7833
+ buffer,
7834
+ bufferLength
7835
+ );
7836
+ },
7837
+ this.pdfiumModule.pdfium.UTF16ToString
7838
+ );
7839
+ const isSelected = this.pdfiumModule.FPDFAnnot_IsOptionSelected(formHandle, annotationPtr, i);
7840
+ options.push({ label, isSelected });
7841
+ }
7842
+ return options;
7070
7843
  }
7071
7844
  /**
7072
7845
  * {@inheritDoc @embedpdf/models!PdfEngine.renderAnnotation}
@@ -7124,11 +7897,30 @@ class PdfiumNative {
7124
7897
  pageCtx.release();
7125
7898
  return PdfTaskHelper.reject({ code: PdfErrorCode.NotFound, message: "annotation not found" });
7126
7899
  }
7900
+ let hasAP = !!this.pdfiumModule.EPDFAnnot_HasAppearanceStream(annotPtr, mode);
7901
+ if (!hasAP && annotation.type === PdfAnnotationSubtype.WIDGET) {
7902
+ if (!this.pdfiumModule.FPDFAnnot_HasKey(annotPtr, "AP")) {
7903
+ this.pdfiumModule.EPDFAnnot_GenerateFormFieldAP(annotPtr);
7904
+ hasAP = !!this.pdfiumModule.EPDFAnnot_HasAppearanceStream(annotPtr, mode);
7905
+ }
7906
+ }
7907
+ if (!hasAP) {
7908
+ this.pdfiumModule.FPDFPage_CloseAnnot(annotPtr);
7909
+ pageCtx.release();
7910
+ this.logger.perf(
7911
+ LOG_SOURCE,
7912
+ LOG_CATEGORY,
7913
+ `RenderPageAnnotation`,
7914
+ "End",
7915
+ `${doc.id}-${page.index}-${annotation.id}`
7916
+ );
7917
+ task.resolve({ data: new Uint8ClampedArray(4), width: 1, height: 1 });
7918
+ return task;
7919
+ }
7127
7920
  const finalScale = Math.max(0.01, scaleFactor * dpr);
7128
7921
  const unrotated = !!(options == null ? void 0 : options.unrotated) && !!annotation.unrotatedRect;
7129
7922
  const renderRect = unrotated ? annotation.unrotatedRect : annotation.rect;
7130
- const rect = toIntRect(renderRect);
7131
- const devRect = toIntRect(transformRect(page.size, rect, rotation, finalScale));
7923
+ const devRect = toIntRect(transformRect(page.size, renderRect, rotation, finalScale));
7132
7924
  const wDev = Math.max(1, devRect.size.width);
7133
7925
  const hDev = Math.max(1, devRect.size.height);
7134
7926
  const stride = wDev * 4;
@@ -7142,13 +7934,7 @@ class PdfiumNative {
7142
7934
  stride
7143
7935
  );
7144
7936
  this.pdfiumModule.FPDFBitmap_FillRect(bitmapPtr, 0, 0, wDev, hDev, 0);
7145
- const M = buildUserToDeviceMatrix(
7146
- rect,
7147
- // {origin:{L,B}, size:{W,H}}
7148
- rotation,
7149
- wDev,
7150
- hDev
7151
- );
7937
+ const M = buildUserToDeviceMatrix(renderRect, rotation, wDev, hDev);
7152
7938
  const mPtr = this.memoryManager.malloc(6 * 4);
7153
7939
  const mView = new Float32Array(this.pdfiumModule.pdfium.HEAPF32.buffer, mPtr, 6);
7154
7940
  mView.set([M.a, M.b, M.c, M.d, M.e, M.f]);
@@ -7299,10 +8085,20 @@ class PdfiumNative {
7299
8085
  * @private
7300
8086
  */
7301
8087
  renderSingleAnnotAppearance(doc, page, pageCtx, annotPtr, mode, rotation, finalScale) {
8088
+ if (!this.pdfiumModule.EPDFAnnot_HasAppearanceStream(annotPtr, mode)) {
8089
+ const subtype = this.pdfiumModule.FPDFAnnot_GetSubtype(annotPtr);
8090
+ if (subtype === PdfAnnotationSubtype.WIDGET && !this.pdfiumModule.FPDFAnnot_HasKey(annotPtr, "AP")) {
8091
+ this.pdfiumModule.EPDFAnnot_GenerateFormFieldAP(annotPtr);
8092
+ if (!this.pdfiumModule.EPDFAnnot_HasAppearanceStream(annotPtr, mode)) {
8093
+ return null;
8094
+ }
8095
+ } else {
8096
+ return null;
8097
+ }
8098
+ }
7302
8099
  const pageRect = this.readPageAnnoRect(annotPtr);
7303
8100
  const annotRect = this.convertPageRectToDeviceRect(doc, page, pageRect);
7304
- const rect = toIntRect(annotRect);
7305
- const devRect = toIntRect(transformRect(page.size, rect, rotation, finalScale));
8101
+ const devRect = toIntRect(transformRect(page.size, annotRect, rotation, finalScale));
7306
8102
  const wDev = Math.max(1, devRect.size.width);
7307
8103
  const hDev = Math.max(1, devRect.size.height);
7308
8104
  const stride = wDev * 4;
@@ -7316,7 +8112,7 @@ class PdfiumNative {
7316
8112
  stride
7317
8113
  );
7318
8114
  this.pdfiumModule.FPDFBitmap_FillRect(bitmapPtr, 0, 0, wDev, hDev, 0);
7319
- const M = buildUserToDeviceMatrix(rect, rotation, wDev, hDev);
8115
+ const M = buildUserToDeviceMatrix(annotRect, rotation, wDev, hDev);
7320
8116
  const mPtr = this.memoryManager.malloc(6 * 4);
7321
8117
  const mView = new Float32Array(this.pdfiumModule.pdfium.HEAPF32.buffer, mPtr, 6);
7322
8118
  mView.set([M.a, M.b, M.c, M.d, M.e, M.f]);
@@ -7370,7 +8166,6 @@ class PdfiumNative {
7370
8166
  const bytes = stride * hDev;
7371
8167
  const pageCtx = ctx.acquirePage(page.index);
7372
8168
  const shouldRenderForms = (options == null ? void 0 : options.withForms) ?? false;
7373
- const formHandle = shouldRenderForms ? pageCtx.getFormHandle() : void 0;
7374
8169
  const heapPtr = this.memoryManager.malloc(bytes);
7375
8170
  const bitmapPtr = this.pdfiumModule.FPDFBitmap_CreateEx(
7376
8171
  wDev,
@@ -7397,20 +8192,22 @@ class PdfiumNative {
7397
8192
  clipPtr,
7398
8193
  flags
7399
8194
  );
7400
- if (formHandle !== void 0) {
7401
- const formParams = computeFormDrawParams(M, rect, page.size, rotation);
7402
- const { startX, startY, formsWidth, formsHeight, scaleX, scaleY } = formParams;
7403
- this.pdfiumModule.FPDF_FFLDraw(
7404
- formHandle,
7405
- bitmapPtr,
7406
- pageCtx.pagePtr,
7407
- startX,
7408
- startY,
7409
- formsWidth,
7410
- formsHeight,
7411
- rotation,
7412
- flags
7413
- );
8195
+ if (shouldRenderForms) {
8196
+ pageCtx.withFormHandle((formHandle) => {
8197
+ const formParams = computeFormDrawParams(M, rect, page.size, rotation);
8198
+ const { startX, startY, formsWidth, formsHeight } = formParams;
8199
+ this.pdfiumModule.FPDF_FFLDraw(
8200
+ formHandle,
8201
+ bitmapPtr,
8202
+ pageCtx.pagePtr,
8203
+ startX,
8204
+ startY,
8205
+ formsWidth,
8206
+ formsHeight,
8207
+ rotation,
8208
+ flags
8209
+ );
8210
+ });
7414
8211
  }
7415
8212
  } finally {
7416
8213
  pageCtx.release();
@@ -7988,10 +8785,10 @@ class PdfiumNative {
7988
8785
  * @private
7989
8786
  */
7990
8787
  setPageAnnoRect(doc, page, annotPtr, rect) {
7991
- const x0d = Math.floor(rect.origin.x);
7992
- const y0d = Math.floor(rect.origin.y);
7993
- const x1d = Math.floor(rect.origin.x + rect.size.width);
7994
- const y1d = Math.floor(rect.origin.y + rect.size.height);
8788
+ const x0d = rect.origin.x;
8789
+ const y0d = rect.origin.y;
8790
+ const x1d = rect.origin.x + rect.size.width;
8791
+ const y1d = rect.origin.y + rect.size.height;
7995
8792
  const TL = this.convertDevicePointToPagePoint(doc, page, { x: x0d, y: y0d });
7996
8793
  const TR = this.convertDevicePointToPagePoint(doc, page, { x: x1d, y: y0d });
7997
8794
  const BR = this.convertDevicePointToPagePoint(doc, page, { x: x1d, y: y1d });
@@ -8134,16 +8931,26 @@ class PdfiumNative {
8134
8931
  }
8135
8932
  const results = {};
8136
8933
  const total = pages.length;
8137
- for (let i = 0; i < pages.length; i++) {
8138
- const page = pages[i];
8139
- const annotations = this.readPageAnnotationsRaw(doc, ctx, page);
8140
- results[page.index] = annotations;
8141
- task.progress({
8142
- pageIndex: page.index,
8143
- result: annotations,
8144
- completed: i + 1,
8145
- total
8146
- });
8934
+ const formInfoPtr = this.pdfiumModule.PDFiumExt_OpenFormFillInfo();
8935
+ const formHandle = this.pdfiumModule.PDFiumExt_InitFormFillEnvironment(
8936
+ ctx.docPtr,
8937
+ formInfoPtr
8938
+ );
8939
+ try {
8940
+ for (let i = 0; i < pages.length; i++) {
8941
+ const page = pages[i];
8942
+ const annotations = this.readPageAnnotationsRaw(doc, ctx, page, formHandle);
8943
+ results[page.index] = annotations;
8944
+ task.progress({
8945
+ pageIndex: page.index,
8946
+ result: annotations,
8947
+ completed: i + 1,
8948
+ total
8949
+ });
8950
+ }
8951
+ } finally {
8952
+ this.pdfiumModule.PDFiumExt_ExitFormFillEnvironment(formHandle);
8953
+ this.pdfiumModule.PDFiumExt_CloseFormFillInfo(formInfoPtr);
8147
8954
  }
8148
8955
  this.logger.perf(LOG_SOURCE, LOG_CATEGORY, "GetAnnotationsBatch", "End", doc.id);
8149
8956
  task.resolve(results);
@@ -8559,4 +9366,4 @@ export {
8559
9366
  isValidCustomKey as i,
8560
9367
  readArrayBuffer as r
8561
9368
  };
8562
- //# sourceMappingURL=direct-engine-D-Jf9yyY.js.map
9369
+ //# sourceMappingURL=direct-engine-4LZYs06h.js.map