@embedpdf/engines 2.5.0 → 2.6.1

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 (46) hide show
  1. package/dist/{browser-qfUHZxQ6.js → browser-BISJ9naB.js} +3 -3
  2. package/dist/{browser-qfUHZxQ6.js.map → browser-BISJ9naB.js.map} +1 -1
  3. package/dist/direct-engine-BaKyNZkO.cjs +2 -0
  4. package/dist/direct-engine-BaKyNZkO.cjs.map +1 -0
  5. package/dist/{direct-engine-D8HGqcIt.js → direct-engine-BmntIHbH.js} +643 -81
  6. package/dist/direct-engine-BmntIHbH.js.map +1 -0
  7. package/dist/index.cjs +1 -1
  8. package/dist/index.cjs.map +1 -1
  9. package/dist/index.js +19 -10
  10. package/dist/index.js.map +1 -1
  11. package/dist/lib/converters/index.js +3 -3
  12. package/dist/lib/orchestrator/pdf-engine.d.ts +4 -1
  13. package/dist/lib/orchestrator/remote-executor.d.ts +2 -1
  14. package/dist/lib/pdfium/engine.d.ts +89 -2
  15. package/dist/lib/pdfium/index.cjs +1 -1
  16. package/dist/lib/pdfium/index.js +11 -11
  17. package/dist/lib/pdfium/web/direct-engine.cjs +1 -1
  18. package/dist/lib/pdfium/web/direct-engine.js +4 -4
  19. package/dist/lib/pdfium/web/worker-engine.cjs +1 -1
  20. package/dist/lib/pdfium/web/worker-engine.cjs.map +1 -1
  21. package/dist/lib/pdfium/web/worker-engine.js +6 -3
  22. package/dist/lib/pdfium/web/worker-engine.js.map +1 -1
  23. package/dist/lib/webworker/engine.cjs +1 -1
  24. package/dist/lib/webworker/engine.cjs.map +1 -1
  25. package/dist/lib/webworker/engine.d.ts +19 -1
  26. package/dist/lib/webworker/engine.js +45 -1
  27. package/dist/lib/webworker/engine.js.map +1 -1
  28. package/dist/{pdf-engine-aJNoNMbt.js → pdf-engine-C07l7iNd.js} +29 -1
  29. package/dist/pdf-engine-C07l7iNd.js.map +1 -0
  30. package/dist/pdf-engine-DUjCt3HC.cjs +2 -0
  31. package/dist/pdf-engine-DUjCt3HC.cjs.map +1 -0
  32. package/dist/preact/index.cjs +1 -1
  33. package/dist/preact/index.js +1 -1
  34. package/dist/react/index.cjs +1 -1
  35. package/dist/react/index.js +1 -1
  36. package/dist/svelte/index.cjs +1 -1
  37. package/dist/svelte/index.js +1 -1
  38. package/dist/vue/index.cjs +1 -1
  39. package/dist/vue/index.js +1 -1
  40. package/package.json +6 -6
  41. package/dist/direct-engine-BtiOvMLP.cjs +0 -2
  42. package/dist/direct-engine-BtiOvMLP.cjs.map +0 -1
  43. package/dist/direct-engine-D8HGqcIt.js.map +0 -1
  44. package/dist/pdf-engine-BmrecQLq.cjs +0 -2
  45. package/dist/pdf-engine-BmrecQLq.cjs.map +0 -1
  46. package/dist/pdf-engine-aJNoNMbt.js.map +0 -1
@@ -1,7 +1,7 @@
1
1
  import { init } from "@embedpdf/pdfium";
2
2
  import { Rotation, NoopLogger, PdfTaskHelper, PdfErrorCode, pdfDateToDate, isUuidV4, uuidV4, PdfAnnotationSubtype, PdfPageFlattenFlag, stripPdfUnwantedMarkers, PdfAnnotationIcon, PdfAnnotationBorderStyle, PdfAnnotationColorType, PdfAnnotationLineEnding, PdfStandardFont, PdfStampFit, PdfTrappedStatus, pdfColorToWebColor, webColorToPdfColor, pdfAlphaToWebOpacity, webOpacityToPdfAlpha, PdfAnnotationReplyType, dateToPdfDate, quadToRect, rectToQuad, PdfPageObjectType, flagsToNames, namesToFlags, PDF_FORM_FIELD_TYPE, AppearanceMode, Task, toIntRect, transformRect, buildUserToDeviceMatrix, PdfZoomMode, PdfActionType } from "@embedpdf/models";
3
- import { P as PdfEngine } from "./pdf-engine-aJNoNMbt.js";
4
- import { b as browserImageDataToBlobConverter } from "./browser-qfUHZxQ6.js";
3
+ import { P as PdfEngine } from "./pdf-engine-C07l7iNd.js";
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);
7
7
  for (let i = 0; i < defaultLength; i++) {
@@ -1567,10 +1567,17 @@ class PdfiumNative {
1567
1567
  message: "can not set the rect of the annotation"
1568
1568
  });
1569
1569
  }
1570
+ const saveAnnotation = this.prepareAnnotationForSave(annotation);
1570
1571
  let isSucceed = false;
1571
- switch (annotation.type) {
1572
+ switch (saveAnnotation.type) {
1572
1573
  case PdfAnnotationSubtype.INK:
1573
- isSucceed = this.addInkStroke(doc, page, pageCtx.pagePtr, annotationPtr, annotation);
1574
+ isSucceed = this.addInkStroke(
1575
+ doc,
1576
+ page,
1577
+ pageCtx.pagePtr,
1578
+ annotationPtr,
1579
+ saveAnnotation
1580
+ );
1574
1581
  break;
1575
1582
  case PdfAnnotationSubtype.STAMP:
1576
1583
  isSucceed = this.addStampContent(
@@ -1579,26 +1586,50 @@ class PdfiumNative {
1579
1586
  page,
1580
1587
  pageCtx.pagePtr,
1581
1588
  annotationPtr,
1582
- annotation,
1589
+ saveAnnotation,
1583
1590
  context == null ? void 0 : context.imageData
1584
1591
  );
1585
1592
  break;
1586
1593
  case PdfAnnotationSubtype.TEXT:
1587
- isSucceed = this.addTextContent(page, pageCtx.pagePtr, annotationPtr, annotation);
1594
+ isSucceed = this.addTextContent(
1595
+ doc,
1596
+ page,
1597
+ pageCtx.pagePtr,
1598
+ annotationPtr,
1599
+ saveAnnotation
1600
+ );
1588
1601
  break;
1589
1602
  case PdfAnnotationSubtype.FREETEXT:
1590
- isSucceed = this.addFreeTextContent(page, pageCtx.pagePtr, annotationPtr, annotation);
1603
+ isSucceed = this.addFreeTextContent(
1604
+ doc,
1605
+ page,
1606
+ pageCtx.pagePtr,
1607
+ annotationPtr,
1608
+ saveAnnotation
1609
+ );
1591
1610
  break;
1592
1611
  case PdfAnnotationSubtype.LINE:
1593
- isSucceed = this.addLineContent(doc, page, pageCtx.pagePtr, annotationPtr, annotation);
1612
+ isSucceed = this.addLineContent(
1613
+ doc,
1614
+ page,
1615
+ pageCtx.pagePtr,
1616
+ annotationPtr,
1617
+ saveAnnotation
1618
+ );
1594
1619
  break;
1595
1620
  case PdfAnnotationSubtype.POLYLINE:
1596
1621
  case PdfAnnotationSubtype.POLYGON:
1597
- isSucceed = this.addPolyContent(doc, page, pageCtx.pagePtr, annotationPtr, annotation);
1622
+ isSucceed = this.addPolyContent(
1623
+ doc,
1624
+ page,
1625
+ pageCtx.pagePtr,
1626
+ annotationPtr,
1627
+ saveAnnotation
1628
+ );
1598
1629
  break;
1599
1630
  case PdfAnnotationSubtype.CIRCLE:
1600
1631
  case PdfAnnotationSubtype.SQUARE:
1601
- isSucceed = this.addShapeContent(page, pageCtx.pagePtr, annotationPtr, annotation);
1632
+ isSucceed = this.addShapeContent(doc, page, pageCtx.pagePtr, annotationPtr, saveAnnotation);
1602
1633
  break;
1603
1634
  case PdfAnnotationSubtype.UNDERLINE:
1604
1635
  case PdfAnnotationSubtype.STRIKEOUT:
@@ -1609,14 +1640,27 @@ class PdfiumNative {
1609
1640
  page,
1610
1641
  pageCtx.pagePtr,
1611
1642
  annotationPtr,
1612
- annotation
1643
+ saveAnnotation
1613
1644
  );
1614
1645
  break;
1615
1646
  case PdfAnnotationSubtype.LINK:
1616
- isSucceed = this.addLinkContent(ctx.docPtr, pageCtx.pagePtr, annotationPtr, annotation);
1647
+ isSucceed = this.addLinkContent(
1648
+ doc,
1649
+ page,
1650
+ ctx.docPtr,
1651
+ pageCtx.pagePtr,
1652
+ annotationPtr,
1653
+ saveAnnotation
1654
+ );
1617
1655
  break;
1618
1656
  case PdfAnnotationSubtype.REDACT:
1619
- isSucceed = this.addRedactContent(doc, page, pageCtx.pagePtr, annotationPtr, annotation);
1657
+ isSucceed = this.addRedactContent(
1658
+ doc,
1659
+ page,
1660
+ pageCtx.pagePtr,
1661
+ annotationPtr,
1662
+ saveAnnotation
1663
+ );
1620
1664
  break;
1621
1665
  }
1622
1666
  if (!isSucceed) {
@@ -1711,43 +1755,81 @@ class PdfiumNative {
1711
1755
  message: "failed to move annotation"
1712
1756
  });
1713
1757
  }
1758
+ const saveAnnotation = this.prepareAnnotationForSave(annotation);
1714
1759
  let ok = false;
1715
- switch (annotation.type) {
1760
+ switch (saveAnnotation.type) {
1716
1761
  /* ── Ink ─────────────────────────────────────────────────────────────── */
1717
1762
  case PdfAnnotationSubtype.INK: {
1718
1763
  if (!this.pdfiumModule.FPDFAnnot_RemoveInkList(annotPtr)) break;
1719
- ok = this.addInkStroke(doc, page, pageCtx.pagePtr, annotPtr, annotation);
1764
+ ok = this.addInkStroke(
1765
+ doc,
1766
+ page,
1767
+ pageCtx.pagePtr,
1768
+ annotPtr,
1769
+ saveAnnotation
1770
+ );
1720
1771
  break;
1721
1772
  }
1722
1773
  /* ── Stamp ───────────────────────────────────────────────────────────── */
1723
1774
  case PdfAnnotationSubtype.STAMP: {
1724
- ok = this.addStampContent(doc, ctx.docPtr, page, pageCtx.pagePtr, annotPtr, annotation);
1775
+ ok = this.addStampContent(
1776
+ doc,
1777
+ ctx.docPtr,
1778
+ page,
1779
+ pageCtx.pagePtr,
1780
+ annotPtr,
1781
+ saveAnnotation
1782
+ );
1725
1783
  break;
1726
1784
  }
1727
1785
  case PdfAnnotationSubtype.TEXT: {
1728
- ok = this.addTextContent(page, pageCtx.pagePtr, annotPtr, annotation);
1786
+ ok = this.addTextContent(
1787
+ doc,
1788
+ page,
1789
+ pageCtx.pagePtr,
1790
+ annotPtr,
1791
+ saveAnnotation
1792
+ );
1729
1793
  break;
1730
1794
  }
1731
1795
  /* ── Free text ────────────────────────────────────────────────────────── */
1732
1796
  case PdfAnnotationSubtype.FREETEXT: {
1733
- ok = this.addFreeTextContent(page, pageCtx.pagePtr, annotPtr, annotation);
1797
+ ok = this.addFreeTextContent(
1798
+ doc,
1799
+ page,
1800
+ pageCtx.pagePtr,
1801
+ annotPtr,
1802
+ saveAnnotation
1803
+ );
1734
1804
  break;
1735
1805
  }
1736
1806
  /* ── Shape ───────────────────────────────────────────────────────────── */
1737
1807
  case PdfAnnotationSubtype.CIRCLE:
1738
1808
  case PdfAnnotationSubtype.SQUARE: {
1739
- ok = this.addShapeContent(page, pageCtx.pagePtr, annotPtr, annotation);
1809
+ ok = this.addShapeContent(doc, page, pageCtx.pagePtr, annotPtr, saveAnnotation);
1740
1810
  break;
1741
1811
  }
1742
1812
  /* ── Line ─────────────────────────────────────────────────────────────── */
1743
1813
  case PdfAnnotationSubtype.LINE: {
1744
- ok = this.addLineContent(doc, page, pageCtx.pagePtr, annotPtr, annotation);
1814
+ ok = this.addLineContent(
1815
+ doc,
1816
+ page,
1817
+ pageCtx.pagePtr,
1818
+ annotPtr,
1819
+ saveAnnotation
1820
+ );
1745
1821
  break;
1746
1822
  }
1747
1823
  /* ── Polygon / Polyline ───────────────────────────────────────────────── */
1748
1824
  case PdfAnnotationSubtype.POLYGON:
1749
1825
  case PdfAnnotationSubtype.POLYLINE: {
1750
- ok = this.addPolyContent(doc, page, pageCtx.pagePtr, annotPtr, annotation);
1826
+ ok = this.addPolyContent(
1827
+ doc,
1828
+ page,
1829
+ pageCtx.pagePtr,
1830
+ annotPtr,
1831
+ saveAnnotation
1832
+ );
1751
1833
  break;
1752
1834
  }
1753
1835
  /* ── Text-markup family ──────────────────────────────────────────────── */
@@ -1755,17 +1837,36 @@ class PdfiumNative {
1755
1837
  case PdfAnnotationSubtype.UNDERLINE:
1756
1838
  case PdfAnnotationSubtype.STRIKEOUT:
1757
1839
  case PdfAnnotationSubtype.SQUIGGLY: {
1758
- ok = this.addTextMarkupContent(doc, page, pageCtx.pagePtr, annotPtr, annotation);
1840
+ ok = this.addTextMarkupContent(
1841
+ doc,
1842
+ page,
1843
+ pageCtx.pagePtr,
1844
+ annotPtr,
1845
+ saveAnnotation
1846
+ );
1759
1847
  break;
1760
1848
  }
1761
1849
  /* ── Link ─────────────────────────────────────────────────────────────── */
1762
1850
  case PdfAnnotationSubtype.LINK: {
1763
- ok = this.addLinkContent(ctx.docPtr, pageCtx.pagePtr, annotPtr, annotation);
1851
+ ok = this.addLinkContent(
1852
+ doc,
1853
+ page,
1854
+ ctx.docPtr,
1855
+ pageCtx.pagePtr,
1856
+ annotPtr,
1857
+ saveAnnotation
1858
+ );
1764
1859
  break;
1765
1860
  }
1766
1861
  /* ── Redact ───────────────────────────────────────────────────────────── */
1767
1862
  case PdfAnnotationSubtype.REDACT: {
1768
- ok = this.addRedactContent(doc, page, pageCtx.pagePtr, annotPtr, annotation);
1863
+ ok = this.addRedactContent(
1864
+ doc,
1865
+ page,
1866
+ pageCtx.pagePtr,
1867
+ annotPtr,
1868
+ saveAnnotation
1869
+ );
1769
1870
  break;
1770
1871
  }
1771
1872
  /* ── Unsupported edits – fall through to error ───────────────────────── */
@@ -2749,7 +2850,7 @@ class PdfiumNative {
2749
2850
  *
2750
2851
  * @private
2751
2852
  */
2752
- addTextContent(page, pagePtr, annotationPtr, annotation) {
2853
+ addTextContent(doc, page, pagePtr, annotationPtr, annotation) {
2753
2854
  if (!this.setAnnotationIcon(annotationPtr, annotation.icon || PdfAnnotationIcon.Comment)) {
2754
2855
  return false;
2755
2856
  }
@@ -2764,7 +2865,7 @@ class PdfiumNative {
2764
2865
  return false;
2765
2866
  }
2766
2867
  }
2767
- return this.applyBaseAnnotationProperties(pagePtr, annotationPtr, annotation);
2868
+ return this.applyBaseAnnotationProperties(doc, page, pagePtr, annotationPtr, annotation);
2768
2869
  }
2769
2870
  /**
2770
2871
  * Add free text content to annotation
@@ -2776,7 +2877,7 @@ class PdfiumNative {
2776
2877
  *
2777
2878
  * @private
2778
2879
  */
2779
- addFreeTextContent(page, pagePtr, annotationPtr, annotation) {
2880
+ addFreeTextContent(doc, page, pagePtr, annotationPtr, annotation) {
2780
2881
  if (!this.setBorderStyle(annotationPtr, PdfAnnotationBorderStyle.SOLID, 0)) {
2781
2882
  return false;
2782
2883
  }
@@ -2808,7 +2909,7 @@ class PdfiumNative {
2808
2909
  } else if (!this.setAnnotationColor(annotationPtr, bgColor ?? "#FFFFFF", PdfAnnotationColorType.Color)) {
2809
2910
  return false;
2810
2911
  }
2811
- return this.applyBaseAnnotationProperties(pagePtr, annotationPtr, annotation);
2912
+ return this.applyBaseAnnotationProperties(doc, page, pagePtr, annotationPtr, annotation);
2812
2913
  }
2813
2914
  /**
2814
2915
  * Set the rect of specified annotation
@@ -2834,7 +2935,7 @@ class PdfiumNative {
2834
2935
  if (!this.setAnnotationColor(annotationPtr, strokeColor, PdfAnnotationColorType.Color)) {
2835
2936
  return false;
2836
2937
  }
2837
- return this.applyBaseAnnotationProperties(pagePtr, annotationPtr, annotation);
2938
+ return this.applyBaseAnnotationProperties(doc, page, pagePtr, annotationPtr, annotation);
2838
2939
  }
2839
2940
  /**
2840
2941
  * Add line content to annotation
@@ -2894,7 +2995,7 @@ class PdfiumNative {
2894
2995
  )) {
2895
2996
  return false;
2896
2997
  }
2897
- return this.applyBaseAnnotationProperties(pagePtr, annotationPtr, annotation);
2998
+ return this.applyBaseAnnotationProperties(doc, page, pagePtr, annotationPtr, annotation);
2898
2999
  }
2899
3000
  /**
2900
3001
  * Add polygon or polyline content to annotation
@@ -2948,7 +3049,7 @@ class PdfiumNative {
2948
3049
  )) {
2949
3050
  return false;
2950
3051
  }
2951
- return this.applyBaseAnnotationProperties(pagePtr, annotationPtr, annotation);
3052
+ return this.applyBaseAnnotationProperties(doc, page, pagePtr, annotationPtr, annotation);
2952
3053
  }
2953
3054
  /**
2954
3055
  * Add link content (action or destination) to a link annotation
@@ -2960,7 +3061,7 @@ class PdfiumNative {
2960
3061
  *
2961
3062
  * @private
2962
3063
  */
2963
- addLinkContent(docPtr, pagePtr, annotationPtr, annotation) {
3064
+ addLinkContent(doc, page, docPtr, pagePtr, annotationPtr, annotation) {
2964
3065
  const style = annotation.strokeStyle ?? PdfAnnotationBorderStyle.UNDERLINE;
2965
3066
  const width = annotation.strokeWidth ?? 2;
2966
3067
  if (!this.setBorderStyle(annotationPtr, style, width)) {
@@ -2983,7 +3084,7 @@ class PdfiumNative {
2983
3084
  return false;
2984
3085
  }
2985
3086
  }
2986
- return this.applyBaseAnnotationProperties(pagePtr, annotationPtr, annotation);
3087
+ return this.applyBaseAnnotationProperties(doc, page, pagePtr, annotationPtr, annotation);
2987
3088
  }
2988
3089
  /**
2989
3090
  * Add shape content to annotation
@@ -2995,7 +3096,7 @@ class PdfiumNative {
2995
3096
  *
2996
3097
  * @private
2997
3098
  */
2998
- addShapeContent(page, pagePtr, annotationPtr, annotation) {
3099
+ addShapeContent(doc, page, pagePtr, annotationPtr, annotation) {
2999
3100
  if (!this.setBorderStyle(annotationPtr, annotation.strokeStyle, annotation.strokeWidth)) {
3000
3101
  return false;
3001
3102
  }
@@ -3023,7 +3124,7 @@ class PdfiumNative {
3023
3124
  )) {
3024
3125
  return false;
3025
3126
  }
3026
- return this.applyBaseAnnotationProperties(pagePtr, annotationPtr, annotation);
3127
+ return this.applyBaseAnnotationProperties(doc, page, pagePtr, annotationPtr, annotation);
3027
3128
  }
3028
3129
  /**
3029
3130
  * Add highlight content to annotation
@@ -3045,7 +3146,7 @@ class PdfiumNative {
3045
3146
  if (!this.setAnnotationColor(annotationPtr, strokeColor, PdfAnnotationColorType.Color)) {
3046
3147
  return false;
3047
3148
  }
3048
- return this.applyBaseAnnotationProperties(pagePtr, annotationPtr, annotation);
3149
+ return this.applyBaseAnnotationProperties(doc, page, pagePtr, annotationPtr, annotation);
3049
3150
  }
3050
3151
  /**
3051
3152
  * Add content to redact annotation
@@ -3112,7 +3213,7 @@ class PdfiumNative {
3112
3213
  if (annotation.textAlign !== void 0 && !this.setAnnotationTextAlignment(annotationPtr, annotation.textAlign)) {
3113
3214
  return false;
3114
3215
  }
3115
- return this.applyBaseAnnotationProperties(pagePtr, annotationPtr, annotation);
3216
+ return this.applyBaseAnnotationProperties(doc, page, pagePtr, annotationPtr, annotation);
3116
3217
  }
3117
3218
  /**
3118
3219
  * Add contents to stamp annotation
@@ -3142,10 +3243,10 @@ class PdfiumNative {
3142
3243
  return false;
3143
3244
  }
3144
3245
  }
3145
- if (!this.pdfiumModule.EPDFAnnot_UpdateAppearanceToRect(annotationPtr, PdfStampFit.Cover)) {
3246
+ if (!this.applyBaseAnnotationProperties(doc, page, pagePtr, annotationPtr, annotation)) {
3146
3247
  return false;
3147
3248
  }
3148
- return this.applyBaseAnnotationProperties(pagePtr, annotationPtr, annotation);
3249
+ return !!this.pdfiumModule.EPDFAnnot_UpdateAppearanceToRect(annotationPtr, PdfStampFit.Cover);
3149
3250
  }
3150
3251
  /**
3151
3252
  * Add image object to annotation
@@ -3664,6 +3765,184 @@ class PdfiumNative {
3664
3765
  }
3665
3766
  return runs;
3666
3767
  }
3768
+ /**
3769
+ * Rich text runs: groups consecutive characters sharing the same
3770
+ * text object, font, size, and fill color into structured segments
3771
+ * with full font metadata and bounding boxes in PDF page coordinates.
3772
+ *
3773
+ * @public
3774
+ */
3775
+ getPageTextRuns(doc, page) {
3776
+ const label = "getPageTextRuns";
3777
+ this.logger.perf(LOG_SOURCE, LOG_CATEGORY, label, "Begin", doc.id);
3778
+ const ctx = this.cache.getContext(doc.id);
3779
+ if (!ctx) {
3780
+ this.logger.perf(LOG_SOURCE, LOG_CATEGORY, label, "End", doc.id);
3781
+ return PdfTaskHelper.reject({
3782
+ code: PdfErrorCode.DocNotOpen,
3783
+ message: "document does not open"
3784
+ });
3785
+ }
3786
+ const pageCtx = ctx.acquirePage(page.index);
3787
+ const textPagePtr = pageCtx.getTextPage();
3788
+ const charCount = this.pdfiumModule.FPDFText_CountChars(textPagePtr);
3789
+ const runs = [];
3790
+ let runStart = 0;
3791
+ let curObjPtr = null;
3792
+ let curFont = null;
3793
+ let curFontSize = 0;
3794
+ let curColor = null;
3795
+ let bounds = null;
3796
+ const flushRun = (end) => {
3797
+ if (curObjPtr === null || curFont === null || curColor === null || bounds === null) return;
3798
+ const count = end - runStart;
3799
+ if (count <= 0) return;
3800
+ const bufPtr = this.memoryManager.malloc(2 * (count + 1));
3801
+ this.pdfiumModule.FPDFText_GetText(textPagePtr, runStart, count, bufPtr);
3802
+ const text = stripPdfUnwantedMarkers(this.pdfiumModule.pdfium.UTF16ToString(bufPtr));
3803
+ this.memoryManager.free(bufPtr);
3804
+ runs.push({
3805
+ text,
3806
+ rect: {
3807
+ origin: { x: bounds.minX, y: bounds.minY },
3808
+ size: {
3809
+ width: Math.max(1, bounds.maxX - bounds.minX),
3810
+ height: Math.max(1, bounds.maxY - bounds.minY)
3811
+ }
3812
+ },
3813
+ font: curFont,
3814
+ fontSize: curFontSize,
3815
+ color: curColor,
3816
+ charIndex: runStart,
3817
+ charCount: count
3818
+ });
3819
+ };
3820
+ const rPtr = this.memoryManager.malloc(4);
3821
+ const gPtr = this.memoryManager.malloc(4);
3822
+ const bPtr = this.memoryManager.malloc(4);
3823
+ const aPtr = this.memoryManager.malloc(4);
3824
+ const rectPtr = this.memoryManager.malloc(16);
3825
+ const dx1Ptr = this.memoryManager.malloc(4);
3826
+ const dy1Ptr = this.memoryManager.malloc(4);
3827
+ const dx2Ptr = this.memoryManager.malloc(4);
3828
+ const dy2Ptr = this.memoryManager.malloc(4);
3829
+ const italicAnglePtr = this.memoryManager.malloc(4);
3830
+ for (let i = 0; i < charCount; i++) {
3831
+ const uc = this.pdfiumModule.FPDFText_GetUnicode(textPagePtr, i);
3832
+ if (uc === 65534 || uc === 65533) continue;
3833
+ const objPtr = this.pdfiumModule.FPDFText_GetTextObject(textPagePtr, i);
3834
+ if (objPtr === 0) continue;
3835
+ const fontSize = this.pdfiumModule.FPDFText_GetFontSize(textPagePtr, i);
3836
+ this.pdfiumModule.FPDFText_GetFillColor(textPagePtr, i, rPtr, gPtr, bPtr, aPtr);
3837
+ const red = this.pdfiumModule.pdfium.getValue(rPtr, "i32") & 255;
3838
+ const green = this.pdfiumModule.pdfium.getValue(gPtr, "i32") & 255;
3839
+ const blue = this.pdfiumModule.pdfium.getValue(bPtr, "i32") & 255;
3840
+ const alpha = this.pdfiumModule.pdfium.getValue(aPtr, "i32") & 255;
3841
+ const fontInfo = this.readFontInfoFromTextObject(objPtr, italicAnglePtr);
3842
+ const needNewRun = curObjPtr === null || objPtr !== curObjPtr || fontInfo.name !== curFont.name || Math.abs(fontSize - curFontSize) > 0.01 || red !== curColor.red || green !== curColor.green || blue !== curColor.blue;
3843
+ if (needNewRun) {
3844
+ flushRun(i);
3845
+ curObjPtr = objPtr;
3846
+ curFont = fontInfo;
3847
+ curFontSize = fontSize;
3848
+ curColor = { red, green, blue, alpha };
3849
+ runStart = i;
3850
+ bounds = null;
3851
+ }
3852
+ if (this.pdfiumModule.FPDFText_GetLooseCharBox(textPagePtr, i, rectPtr)) {
3853
+ const left = this.pdfiumModule.pdfium.getValue(rectPtr, "float");
3854
+ const top = this.pdfiumModule.pdfium.getValue(rectPtr + 4, "float");
3855
+ const right = this.pdfiumModule.pdfium.getValue(rectPtr + 8, "float");
3856
+ const bottom = this.pdfiumModule.pdfium.getValue(rectPtr + 12, "float");
3857
+ if (left !== right && top !== bottom) {
3858
+ this.pdfiumModule.FPDF_PageToDevice(
3859
+ pageCtx.pagePtr,
3860
+ 0,
3861
+ 0,
3862
+ page.size.width,
3863
+ page.size.height,
3864
+ 0,
3865
+ left,
3866
+ top,
3867
+ dx1Ptr,
3868
+ dy1Ptr
3869
+ );
3870
+ this.pdfiumModule.FPDF_PageToDevice(
3871
+ pageCtx.pagePtr,
3872
+ 0,
3873
+ 0,
3874
+ page.size.width,
3875
+ page.size.height,
3876
+ 0,
3877
+ right,
3878
+ bottom,
3879
+ dx2Ptr,
3880
+ dy2Ptr
3881
+ );
3882
+ const x1 = this.pdfiumModule.pdfium.getValue(dx1Ptr, "i32");
3883
+ const y1 = this.pdfiumModule.pdfium.getValue(dy1Ptr, "i32");
3884
+ const x2 = this.pdfiumModule.pdfium.getValue(dx2Ptr, "i32");
3885
+ const y2 = this.pdfiumModule.pdfium.getValue(dy2Ptr, "i32");
3886
+ const cx = Math.min(x1, x2);
3887
+ const cy = Math.min(y1, y2);
3888
+ const cw = Math.abs(x2 - x1);
3889
+ const ch = Math.abs(y2 - y1);
3890
+ if (bounds === null) {
3891
+ bounds = { minX: cx, minY: cy, maxX: cx + cw, maxY: cy + ch };
3892
+ } else {
3893
+ bounds.minX = Math.min(bounds.minX, cx);
3894
+ bounds.minY = Math.min(bounds.minY, cy);
3895
+ bounds.maxX = Math.max(bounds.maxX, cx + cw);
3896
+ bounds.maxY = Math.max(bounds.maxY, cy + ch);
3897
+ }
3898
+ }
3899
+ }
3900
+ }
3901
+ flushRun(charCount);
3902
+ [rPtr, gPtr, bPtr, aPtr, rectPtr, dx1Ptr, dy1Ptr, dx2Ptr, dy2Ptr, italicAnglePtr].forEach(
3903
+ (p) => this.memoryManager.free(p)
3904
+ );
3905
+ pageCtx.release();
3906
+ this.logger.perf(LOG_SOURCE, LOG_CATEGORY, label, "End", doc.id);
3907
+ return PdfTaskHelper.resolve({ runs });
3908
+ }
3909
+ /**
3910
+ * Read font metadata from a text object handle via FPDFFont_* APIs.
3911
+ */
3912
+ readFontInfoFromTextObject(textObjPtr, italicAnglePtr) {
3913
+ const fontPtr = this.pdfiumModule.FPDFTextObj_GetFont(textObjPtr);
3914
+ let name = "";
3915
+ let familyName = "";
3916
+ let weight = 400;
3917
+ let italic = false;
3918
+ let monospaced = false;
3919
+ let embedded = false;
3920
+ if (fontPtr) {
3921
+ const nameLen = this.pdfiumModule.FPDFFont_GetBaseFontName(fontPtr, 0, 0);
3922
+ if (nameLen > 0) {
3923
+ const nameBuf = this.memoryManager.malloc(nameLen + 1);
3924
+ this.pdfiumModule.FPDFFont_GetBaseFontName(fontPtr, nameBuf, nameLen + 1);
3925
+ name = this.pdfiumModule.pdfium.UTF8ToString(nameBuf);
3926
+ this.memoryManager.free(nameBuf);
3927
+ }
3928
+ const famLen = this.pdfiumModule.FPDFFont_GetFamilyName(fontPtr, 0, 0);
3929
+ if (famLen > 0) {
3930
+ const famBuf = this.memoryManager.malloc(famLen + 1);
3931
+ this.pdfiumModule.FPDFFont_GetFamilyName(fontPtr, famBuf, famLen + 1);
3932
+ familyName = this.pdfiumModule.pdfium.UTF8ToString(famBuf);
3933
+ this.memoryManager.free(famBuf);
3934
+ }
3935
+ weight = this.pdfiumModule.FPDFFont_GetWeight(fontPtr);
3936
+ embedded = this.pdfiumModule.FPDFFont_GetIsEmbedded(fontPtr) !== 0;
3937
+ if (this.pdfiumModule.FPDFFont_GetItalicAngle(fontPtr, italicAnglePtr)) {
3938
+ const angle = this.pdfiumModule.pdfium.getValue(italicAnglePtr, "i32");
3939
+ italic = angle !== 0;
3940
+ }
3941
+ const flags = this.pdfiumModule.FPDFFont_GetFlags(fontPtr);
3942
+ monospaced = (flags & 1) !== 0;
3943
+ }
3944
+ return { name, familyName, weight, italic, monospaced, embedded };
3945
+ }
3667
3946
  /**
3668
3947
  * Extract glyph geometry + metadata for `charIndex`
3669
3948
  *
@@ -4045,8 +4324,62 @@ class PdfiumNative {
4045
4324
  }
4046
4325
  break;
4047
4326
  }
4327
+ if (annotation) {
4328
+ annotation = this.reverseRotateAnnotationOnLoad(annotation);
4329
+ }
4048
4330
  return annotation;
4049
4331
  }
4332
+ /**
4333
+ * On load, if a vertex-type annotation has rotation metadata in EPDFCustom,
4334
+ * reverse-rotate the PDF's physically rotated vertices by -rotation to recover
4335
+ * the unrotated vertices for runtime editing.
4336
+ */
4337
+ reverseRotateAnnotationOnLoad(annotation) {
4338
+ const rotation = annotation.rotation;
4339
+ const unrotatedRect = annotation.unrotatedRect;
4340
+ if (!rotation || rotation === 0 || !unrotatedRect) {
4341
+ return annotation;
4342
+ }
4343
+ const center = {
4344
+ x: unrotatedRect.origin.x + unrotatedRect.size.width / 2,
4345
+ y: unrotatedRect.origin.y + unrotatedRect.size.height / 2
4346
+ };
4347
+ switch (annotation.type) {
4348
+ case PdfAnnotationSubtype.INK: {
4349
+ const ink = annotation;
4350
+ const unrotatedInkList = ink.inkList.map((stroke) => ({
4351
+ points: stroke.points.map((p) => this.rotatePointForSave(p, center, -rotation))
4352
+ }));
4353
+ return { ...ink, inkList: unrotatedInkList };
4354
+ }
4355
+ case PdfAnnotationSubtype.LINE: {
4356
+ const line = annotation;
4357
+ return {
4358
+ ...line,
4359
+ linePoints: {
4360
+ start: this.rotatePointForSave(line.linePoints.start, center, -rotation),
4361
+ end: this.rotatePointForSave(line.linePoints.end, center, -rotation)
4362
+ }
4363
+ };
4364
+ }
4365
+ case PdfAnnotationSubtype.POLYGON: {
4366
+ const poly = annotation;
4367
+ return {
4368
+ ...poly,
4369
+ vertices: poly.vertices.map((v) => this.rotatePointForSave(v, center, -rotation))
4370
+ };
4371
+ }
4372
+ case PdfAnnotationSubtype.POLYLINE: {
4373
+ const polyline = annotation;
4374
+ return {
4375
+ ...polyline,
4376
+ vertices: polyline.vertices.map((v) => this.rotatePointForSave(v, center, -rotation))
4377
+ };
4378
+ }
4379
+ default:
4380
+ return annotation;
4381
+ }
4382
+ }
4050
4383
  /**
4051
4384
  * Return the colour stored directly in the annotation dictionary's `/C` entry.
4052
4385
  *
@@ -4139,6 +4472,125 @@ class PdfiumNative {
4139
4472
  const pdfOpacity = webOpacityToPdfAlpha(opacity);
4140
4473
  return this.pdfiumModule.EPDFAnnot_SetOpacity(annotationPtr, pdfOpacity & 255);
4141
4474
  }
4475
+ /**
4476
+ * Get the rotation angle (in degrees) from the annotation's /Rotate entry.
4477
+ * Returns 0 if no rotation is set or on error.
4478
+ *
4479
+ * @param annotationPtr - pointer to the annotation
4480
+ * @returns rotation in degrees (0 if not set)
4481
+ */
4482
+ getAnnotationRotation(annotationPtr) {
4483
+ const rotationPtr = this.memoryManager.malloc(4);
4484
+ const ok = this.pdfiumModule.EPDFAnnot_GetRotate(annotationPtr, rotationPtr);
4485
+ if (!ok) {
4486
+ this.memoryManager.free(rotationPtr);
4487
+ return 0;
4488
+ }
4489
+ const rotation = this.pdfiumModule.pdfium.getValue(rotationPtr, "float");
4490
+ this.memoryManager.free(rotationPtr);
4491
+ return rotation;
4492
+ }
4493
+ /**
4494
+ * Set the rotation angle (in degrees) on the annotation's /Rotate entry.
4495
+ * A value of 0 removes the /Rotate key.
4496
+ *
4497
+ * @param annotationPtr - pointer to the annotation
4498
+ * @param rotation - rotation in degrees (clockwise)
4499
+ * @returns true on success
4500
+ */
4501
+ setAnnotationRotation(annotationPtr, rotation) {
4502
+ return !!this.pdfiumModule.EPDFAnnot_SetRotate(annotationPtr, rotation);
4503
+ }
4504
+ /**
4505
+ * Get the EmbedPDF extended rotation (in degrees) from the annotation's
4506
+ * /EPDFRotate entry. Returns 0 if not set or on error.
4507
+ *
4508
+ * @param annotationPtr - pointer to the annotation
4509
+ * @returns rotation in degrees (0 if not set)
4510
+ */
4511
+ getAnnotExtendedRotation(annotationPtr) {
4512
+ const rotationPtr = this.memoryManager.malloc(4);
4513
+ const ok = this.pdfiumModule.EPDFAnnot_GetExtendedRotation(annotationPtr, rotationPtr);
4514
+ if (!ok) {
4515
+ this.memoryManager.free(rotationPtr);
4516
+ return 0;
4517
+ }
4518
+ const rotation = this.pdfiumModule.pdfium.getValue(rotationPtr, "float");
4519
+ this.memoryManager.free(rotationPtr);
4520
+ return rotation;
4521
+ }
4522
+ /**
4523
+ * Set the EmbedPDF extended rotation (in degrees) on the annotation's
4524
+ * /EPDFRotate entry. A value of 0 removes the key.
4525
+ *
4526
+ * @param annotationPtr - pointer to the annotation
4527
+ * @param rotation - rotation in degrees
4528
+ * @returns true on success
4529
+ */
4530
+ setAnnotExtendedRotation(annotationPtr, rotation) {
4531
+ return !!this.pdfiumModule.EPDFAnnot_SetExtendedRotation(annotationPtr, rotation);
4532
+ }
4533
+ /**
4534
+ * Read the EmbedPDF unrotated rect from the annotation's /EPDFUnrotatedRect
4535
+ * entry. Returns the raw page-space rect (same format as `readPageAnnoRect`)
4536
+ * or null if not set.
4537
+ *
4538
+ * @param annotationPtr - pointer to the annotation
4539
+ * @returns raw `{ left, top, right, bottom }` in page coords, or null
4540
+ */
4541
+ readAnnotUnrotatedRect(annotationPtr) {
4542
+ const rectPtr = this.memoryManager.malloc(4 * 4);
4543
+ const ok = this.pdfiumModule.EPDFAnnot_GetUnrotatedRect(annotationPtr, rectPtr);
4544
+ if (!ok) {
4545
+ this.memoryManager.free(rectPtr);
4546
+ return null;
4547
+ }
4548
+ const left = this.pdfiumModule.pdfium.getValue(rectPtr, "float");
4549
+ const top = this.pdfiumModule.pdfium.getValue(rectPtr + 4, "float");
4550
+ const right = this.pdfiumModule.pdfium.getValue(rectPtr + 8, "float");
4551
+ const bottom = this.pdfiumModule.pdfium.getValue(rectPtr + 12, "float");
4552
+ this.memoryManager.free(rectPtr);
4553
+ if (left === 0 && top === 0 && right === 0 && bottom === 0) {
4554
+ return null;
4555
+ }
4556
+ return { left, top, right, bottom };
4557
+ }
4558
+ /**
4559
+ * Write the EmbedPDF unrotated rect (/EPDFUnrotatedRect) for an annotation.
4560
+ * Accepts a device-space `Rect` and converts to page coordinates internally,
4561
+ * following the same pattern as `setPageAnnoRect`.
4562
+ *
4563
+ * @param doc - pdf document object
4564
+ * @param page - pdf page object
4565
+ * @param annotPtr - pointer to the annotation
4566
+ * @param rect - device-space rect to store as the unrotated rect
4567
+ * @returns true on success
4568
+ */
4569
+ setAnnotUnrotatedRect(doc, page, annotPtr, rect) {
4570
+ const x0d = Math.floor(rect.origin.x);
4571
+ const y0d = Math.floor(rect.origin.y);
4572
+ const x1d = Math.floor(rect.origin.x + rect.size.width);
4573
+ const y1d = Math.floor(rect.origin.y + rect.size.height);
4574
+ const TL = this.convertDevicePointToPagePoint(doc, page, { x: x0d, y: y0d });
4575
+ const TR = this.convertDevicePointToPagePoint(doc, page, { x: x1d, y: y0d });
4576
+ const BR = this.convertDevicePointToPagePoint(doc, page, { x: x1d, y: y1d });
4577
+ const BL = this.convertDevicePointToPagePoint(doc, page, { x: x0d, y: y1d });
4578
+ let left = Math.min(TL.x, TR.x, BR.x, BL.x);
4579
+ let right = Math.max(TL.x, TR.x, BR.x, BL.x);
4580
+ let bottom = Math.min(TL.y, TR.y, BR.y, BL.y);
4581
+ let top = Math.max(TL.y, TR.y, BR.y, BL.y);
4582
+ if (left > right) [left, right] = [right, left];
4583
+ if (bottom > top) [bottom, top] = [top, bottom];
4584
+ const ptr = this.memoryManager.malloc(16);
4585
+ const pdf = this.pdfiumModule.pdfium;
4586
+ pdf.setValue(ptr + 0, left, "float");
4587
+ pdf.setValue(ptr + 4, top, "float");
4588
+ pdf.setValue(ptr + 8, right, "float");
4589
+ pdf.setValue(ptr + 12, bottom, "float");
4590
+ const ok = this.pdfiumModule.EPDFAnnot_SetUnrotatedRect(annotPtr, ptr);
4591
+ this.memoryManager.free(ptr);
4592
+ return !!ok;
4593
+ }
4142
4594
  /**
4143
4595
  * Fetch the `/Q` text-alignment value from a **FreeText** annotation.
4144
4596
  *
@@ -4288,10 +4740,11 @@ class PdfiumNative {
4288
4740
  * @returns `true` on success
4289
4741
  */
4290
4742
  setAnnotationDefaultAppearance(annotationPtr, font, fontSize, color) {
4743
+ const resolvedFont = font === PdfStandardFont.Unknown ? PdfStandardFont.Helvetica : font;
4291
4744
  const { red, green, blue } = webColorToPdfColor(color);
4292
4745
  return !!this.pdfiumModule.EPDFAnnot_SetDefaultAppearance(
4293
4746
  annotationPtr,
4294
- font,
4747
+ resolvedFont,
4295
4748
  fontSize,
4296
4749
  red & 255,
4297
4750
  green & 255,
@@ -4745,7 +5198,7 @@ class PdfiumNative {
4745
5198
  ptr,
4746
5199
  count,
4747
5200
  recurseForms ? true : false,
4748
- drawBlackBoxes ? true : false
5201
+ false
4749
5202
  );
4750
5203
  } finally {
4751
5204
  this.memoryManager.free(ptr);
@@ -4998,7 +5451,7 @@ class PdfiumNative {
4998
5451
  state,
4999
5452
  stateModel,
5000
5453
  icon,
5001
- ...this.readBaseAnnotationProperties(annotationPtr)
5454
+ ...this.readBaseAnnotationProperties(doc, page, annotationPtr)
5002
5455
  };
5003
5456
  }
5004
5457
  /**
@@ -5037,7 +5490,7 @@ class PdfiumNative {
5037
5490
  textAlign,
5038
5491
  defaultStyle,
5039
5492
  richContent,
5040
- ...this.readBaseAnnotationProperties(annotationPtr)
5493
+ ...this.readBaseAnnotationProperties(doc, page, annotationPtr)
5041
5494
  };
5042
5495
  }
5043
5496
  /**
@@ -5085,7 +5538,7 @@ class PdfiumNative {
5085
5538
  strokeWidth,
5086
5539
  strokeStyle,
5087
5540
  strokeDashArray,
5088
- ...this.readBaseAnnotationProperties(annotationPtr)
5541
+ ...this.readBaseAnnotationProperties(doc, page, annotationPtr)
5089
5542
  };
5090
5543
  }
5091
5544
  /**
@@ -5108,7 +5561,7 @@ class PdfiumNative {
5108
5561
  type: PdfAnnotationSubtype.WIDGET,
5109
5562
  rect,
5110
5563
  field,
5111
- ...this.readBaseAnnotationProperties(annotationPtr)
5564
+ ...this.readBaseAnnotationProperties(doc, page, annotationPtr)
5112
5565
  };
5113
5566
  }
5114
5567
  /**
@@ -5128,7 +5581,7 @@ class PdfiumNative {
5128
5581
  id: index,
5129
5582
  type: PdfAnnotationSubtype.FILEATTACHMENT,
5130
5583
  rect,
5131
- ...this.readBaseAnnotationProperties(annotationPtr)
5584
+ ...this.readBaseAnnotationProperties(doc, page, annotationPtr)
5132
5585
  };
5133
5586
  }
5134
5587
  /**
@@ -5162,7 +5615,7 @@ class PdfiumNative {
5162
5615
  opacity,
5163
5616
  strokeWidth: strokeWidth === 0 ? 1 : strokeWidth,
5164
5617
  inkList,
5165
- ...this.readBaseAnnotationProperties(annotationPtr)
5618
+ ...this.readBaseAnnotationProperties(doc, page, annotationPtr)
5166
5619
  };
5167
5620
  }
5168
5621
  /**
@@ -5211,7 +5664,7 @@ class PdfiumNative {
5211
5664
  strokeStyle,
5212
5665
  strokeDashArray,
5213
5666
  vertices,
5214
- ...this.readBaseAnnotationProperties(annotationPtr)
5667
+ ...this.readBaseAnnotationProperties(doc, page, annotationPtr)
5215
5668
  };
5216
5669
  }
5217
5670
  /**
@@ -5255,7 +5708,7 @@ class PdfiumNative {
5255
5708
  strokeDashArray,
5256
5709
  lineEndings,
5257
5710
  vertices,
5258
- ...this.readBaseAnnotationProperties(annotationPtr)
5711
+ ...this.readBaseAnnotationProperties(doc, page, annotationPtr)
5259
5712
  };
5260
5713
  }
5261
5714
  /**
@@ -5302,7 +5755,7 @@ class PdfiumNative {
5302
5755
  start: PdfAnnotationLineEnding.None,
5303
5756
  end: PdfAnnotationLineEnding.None
5304
5757
  },
5305
- ...this.readBaseAnnotationProperties(annotationPtr)
5758
+ ...this.readBaseAnnotationProperties(doc, page, annotationPtr)
5306
5759
  };
5307
5760
  }
5308
5761
  /**
@@ -5332,7 +5785,7 @@ class PdfiumNative {
5332
5785
  color: strokeColor,
5333
5786
  // deprecated alias
5334
5787
  opacity,
5335
- ...this.readBaseAnnotationProperties(annotationPtr)
5788
+ ...this.readBaseAnnotationProperties(doc, page, annotationPtr)
5336
5789
  };
5337
5790
  }
5338
5791
  /**
@@ -5362,7 +5815,7 @@ class PdfiumNative {
5362
5815
  color: strokeColor,
5363
5816
  // deprecated alias
5364
5817
  opacity,
5365
- ...this.readBaseAnnotationProperties(annotationPtr)
5818
+ ...this.readBaseAnnotationProperties(doc, page, annotationPtr)
5366
5819
  };
5367
5820
  }
5368
5821
  /**
@@ -5392,7 +5845,7 @@ class PdfiumNative {
5392
5845
  color: strokeColor,
5393
5846
  // deprecated alias
5394
5847
  opacity,
5395
- ...this.readBaseAnnotationProperties(annotationPtr)
5848
+ ...this.readBaseAnnotationProperties(doc, page, annotationPtr)
5396
5849
  };
5397
5850
  }
5398
5851
  /**
@@ -5422,7 +5875,7 @@ class PdfiumNative {
5422
5875
  color: strokeColor,
5423
5876
  // deprecated alias
5424
5877
  opacity,
5425
- ...this.readBaseAnnotationProperties(annotationPtr)
5878
+ ...this.readBaseAnnotationProperties(doc, page, annotationPtr)
5426
5879
  };
5427
5880
  }
5428
5881
  /**
@@ -5442,7 +5895,7 @@ class PdfiumNative {
5442
5895
  id: index,
5443
5896
  type: PdfAnnotationSubtype.CARET,
5444
5897
  rect,
5445
- ...this.readBaseAnnotationProperties(annotationPtr)
5898
+ ...this.readBaseAnnotationProperties(doc, page, annotationPtr)
5446
5899
  };
5447
5900
  }
5448
5901
  /**
@@ -5485,7 +5938,7 @@ class PdfiumNative {
5485
5938
  fontSize: da == null ? void 0 : da.fontSize,
5486
5939
  fontColor: da == null ? void 0 : da.fontColor,
5487
5940
  textAlign,
5488
- ...this.readBaseAnnotationProperties(annotationPtr)
5941
+ ...this.readBaseAnnotationProperties(doc, page, annotationPtr)
5489
5942
  };
5490
5943
  }
5491
5944
  /**
@@ -5505,7 +5958,7 @@ class PdfiumNative {
5505
5958
  id: index,
5506
5959
  type: PdfAnnotationSubtype.STAMP,
5507
5960
  rect,
5508
- ...this.readBaseAnnotationProperties(annotationPtr)
5961
+ ...this.readBaseAnnotationProperties(doc, page, annotationPtr)
5509
5962
  };
5510
5963
  }
5511
5964
  /**
@@ -5768,7 +6221,7 @@ class PdfiumNative {
5768
6221
  strokeColor: strokeColor ?? "#FF0000",
5769
6222
  strokeStyle,
5770
6223
  ...strokeDashArray !== void 0 && { strokeDashArray },
5771
- ...this.readBaseAnnotationProperties(annotationPtr)
6224
+ ...this.readBaseAnnotationProperties(doc, page, annotationPtr)
5772
6225
  };
5773
6226
  }
5774
6227
  /**
@@ -5808,7 +6261,7 @@ class PdfiumNative {
5808
6261
  strokeWidth,
5809
6262
  strokeStyle,
5810
6263
  ...strokeDashArray !== void 0 && { strokeDashArray },
5811
- ...this.readBaseAnnotationProperties(annotationPtr)
6264
+ ...this.readBaseAnnotationProperties(doc, page, annotationPtr)
5812
6265
  };
5813
6266
  }
5814
6267
  /**
@@ -5829,7 +6282,7 @@ class PdfiumNative {
5829
6282
  id: index,
5830
6283
  type,
5831
6284
  rect,
5832
- ...this.readBaseAnnotationProperties(annotationPtr)
6285
+ ...this.readBaseAnnotationProperties(doc, page, annotationPtr)
5833
6286
  };
5834
6287
  }
5835
6288
  /**
@@ -5861,6 +6314,73 @@ class PdfiumNative {
5861
6314
  if (!parentPtr) return false;
5862
6315
  return this.pdfiumModule.EPDFAnnot_SetLinkedAnnot(annotationPtr, "IRT", parentPtr);
5863
6316
  }
6317
+ /**
6318
+ * Rotate a point around a center by the given angle in degrees.
6319
+ * Used to rotate vertices for PDF storage.
6320
+ */
6321
+ rotatePointForSave(point, center, angleDegrees) {
6322
+ const rad = angleDegrees * Math.PI / 180;
6323
+ const cos = Math.cos(rad);
6324
+ const sin = Math.sin(rad);
6325
+ const dx = point.x - center.x;
6326
+ const dy = point.y - center.y;
6327
+ return {
6328
+ x: center.x + dx * cos - dy * sin,
6329
+ y: center.y + dx * sin + dy * cos
6330
+ };
6331
+ }
6332
+ /**
6333
+ * Prepare an annotation for saving to PDF.
6334
+ * For vertex types (ink, line, polygon, polyline) with rotation,
6335
+ * physically rotates the vertices by +rotation so that other PDF viewers
6336
+ * see the correct visual result. Our viewer reverse-rotates on load.
6337
+ */
6338
+ prepareAnnotationForSave(annotation) {
6339
+ const rotation = annotation.rotation;
6340
+ const unrotatedRect = annotation.unrotatedRect;
6341
+ if (!rotation || rotation === 0 || !unrotatedRect) {
6342
+ return annotation;
6343
+ }
6344
+ const center = {
6345
+ x: unrotatedRect.origin.x + unrotatedRect.size.width / 2,
6346
+ y: unrotatedRect.origin.y + unrotatedRect.size.height / 2
6347
+ };
6348
+ switch (annotation.type) {
6349
+ case PdfAnnotationSubtype.INK: {
6350
+ const ink = annotation;
6351
+ const rotatedInkList = ink.inkList.map((stroke) => ({
6352
+ points: stroke.points.map((p) => this.rotatePointForSave(p, center, rotation))
6353
+ }));
6354
+ return { ...ink, inkList: rotatedInkList };
6355
+ }
6356
+ case PdfAnnotationSubtype.LINE: {
6357
+ const line = annotation;
6358
+ return {
6359
+ ...line,
6360
+ linePoints: {
6361
+ start: this.rotatePointForSave(line.linePoints.start, center, rotation),
6362
+ end: this.rotatePointForSave(line.linePoints.end, center, rotation)
6363
+ }
6364
+ };
6365
+ }
6366
+ case PdfAnnotationSubtype.POLYGON: {
6367
+ const poly = annotation;
6368
+ return {
6369
+ ...poly,
6370
+ vertices: poly.vertices.map((v) => this.rotatePointForSave(v, center, rotation))
6371
+ };
6372
+ }
6373
+ case PdfAnnotationSubtype.POLYLINE: {
6374
+ const polyline = annotation;
6375
+ return {
6376
+ ...polyline,
6377
+ vertices: polyline.vertices.map((v) => this.rotatePointForSave(v, center, rotation))
6378
+ };
6379
+ }
6380
+ default:
6381
+ return annotation;
6382
+ }
6383
+ }
5864
6384
  /**
5865
6385
  * Apply all base annotation properties from PdfAnnotationObjectBase.
5866
6386
  * The setInReplyToId and setReplyType functions handle clearing when undefined.
@@ -5870,7 +6390,7 @@ class PdfiumNative {
5870
6390
  * @param annotation - the annotation object containing properties to apply
5871
6391
  * @returns `true` on success
5872
6392
  */
5873
- applyBaseAnnotationProperties(pagePtr, annotationPtr, annotation) {
6393
+ applyBaseAnnotationProperties(doc, page, pagePtr, annotationPtr, annotation) {
5874
6394
  if (!this.setAnnotString(annotationPtr, "T", annotation.author || "")) {
5875
6395
  return false;
5876
6396
  }
@@ -5892,11 +6412,32 @@ class PdfiumNative {
5892
6412
  return false;
5893
6413
  }
5894
6414
  }
5895
- if (annotation.custom) {
5896
- if (!this.setAnnotCustom(annotationPtr, annotation.custom)) {
6415
+ const existingCustom = this.getAnnotCustom(annotationPtr) ?? {};
6416
+ const customData = {
6417
+ ...existingCustom,
6418
+ ...annotation.custom ?? {}
6419
+ };
6420
+ delete customData.unrotatedRect;
6421
+ delete customData.rotation;
6422
+ const hasCustomData = Object.keys(customData).length > 0;
6423
+ if (hasCustomData) {
6424
+ if (!this.setAnnotCustom(annotationPtr, customData)) {
6425
+ return false;
6426
+ }
6427
+ } else if (Object.keys(existingCustom).length > 0) {
6428
+ if (!this.setAnnotCustom(annotationPtr, null)) {
5897
6429
  return false;
5898
6430
  }
5899
6431
  }
6432
+ if (annotation.rotation !== void 0) {
6433
+ const pdfRotation = annotation.rotation ? (360 - annotation.rotation) % 360 : 0;
6434
+ this.setAnnotExtendedRotation(annotationPtr, pdfRotation);
6435
+ }
6436
+ if (annotation.unrotatedRect) {
6437
+ this.setAnnotUnrotatedRect(doc, page, annotationPtr, annotation.unrotatedRect);
6438
+ } else if (annotation.rotation && annotation.rotation !== 0) {
6439
+ this.setAnnotUnrotatedRect(doc, page, annotationPtr, annotation.rect);
6440
+ }
5900
6441
  if (!this.setInReplyToId(pagePtr, annotationPtr, annotation.inReplyToId)) {
5901
6442
  return false;
5902
6443
  }
@@ -5909,10 +6450,12 @@ class PdfiumNative {
5909
6450
  * Read all base annotation properties from PdfAnnotationObjectBase.
5910
6451
  * Returns an object that can be spread into the annotation return value.
5911
6452
  *
6453
+ * @param doc - pdf document object
6454
+ * @param page - pdf page object
5912
6455
  * @param annotationPtr - pointer to annotation object
5913
6456
  * @returns object with base annotation properties
5914
6457
  */
5915
- readBaseAnnotationProperties(annotationPtr) {
6458
+ readBaseAnnotationProperties(doc, page, annotationPtr) {
5916
6459
  const author = this.getAnnotString(annotationPtr, "T");
5917
6460
  const contents = this.getAnnotString(annotationPtr, "Contents") || "";
5918
6461
  const modified = this.getAnnotationDate(annotationPtr, "M");
@@ -5921,6 +6464,10 @@ class PdfiumNative {
5921
6464
  const custom = this.getAnnotCustom(annotationPtr);
5922
6465
  const inReplyToId = this.getInReplyToId(annotationPtr);
5923
6466
  const replyType = this.getReplyType(annotationPtr);
6467
+ const pdfRotation = this.getAnnotExtendedRotation(annotationPtr);
6468
+ const rotation = pdfRotation !== 0 ? (360 - pdfRotation) % 360 : 0;
6469
+ const rawUnrotatedRect = this.readAnnotUnrotatedRect(annotationPtr);
6470
+ const unrotatedRect = rawUnrotatedRect ? this.convertPageRectToDeviceRect(doc, page, rawUnrotatedRect) : void 0;
5924
6471
  return {
5925
6472
  author,
5926
6473
  contents,
@@ -5931,7 +6478,9 @@ class PdfiumNative {
5931
6478
  // Only include IRT if present
5932
6479
  ...inReplyToId && { inReplyToId },
5933
6480
  // Only include RT if present and not the default (Reply)
5934
- ...replyType && replyType !== PdfAnnotationReplyType.Reply && { replyType }
6481
+ ...replyType && replyType !== PdfAnnotationReplyType.Reply && { replyType },
6482
+ ...rotation !== 0 && { rotation },
6483
+ ...unrotatedRect !== void 0 && { unrotatedRect }
5935
6484
  };
5936
6485
  }
5937
6486
  /**
@@ -6359,7 +6908,9 @@ class PdfiumNative {
6359
6908
  return PdfTaskHelper.reject({ code: PdfErrorCode.NotFound, message: "annotation not found" });
6360
6909
  }
6361
6910
  const finalScale = Math.max(0.01, scaleFactor * dpr);
6362
- const rect = toIntRect(annotation.rect);
6911
+ const unrotated = !!(options == null ? void 0 : options.unrotated) && !!annotation.unrotatedRect;
6912
+ const renderRect = unrotated ? annotation.unrotatedRect : annotation.rect;
6913
+ const rect = toIntRect(renderRect);
6363
6914
  const devRect = toIntRect(transformRect(page.size, rect, rotation, finalScale));
6364
6915
  const wDev = Math.max(1, devRect.size.width);
6365
6916
  const hDev = Math.max(1, devRect.size.height);
@@ -6387,14 +6938,25 @@ class PdfiumNative {
6387
6938
  const FLAGS = 16;
6388
6939
  let ok = false;
6389
6940
  try {
6390
- ok = !!this.pdfiumModule.EPDF_RenderAnnotBitmap(
6391
- bitmapPtr,
6392
- pageCtx.pagePtr,
6393
- annotPtr,
6394
- mode,
6395
- mPtr,
6396
- FLAGS
6397
- );
6941
+ if (unrotated) {
6942
+ ok = !!this.pdfiumModule.EPDF_RenderAnnotBitmapUnrotated(
6943
+ bitmapPtr,
6944
+ pageCtx.pagePtr,
6945
+ annotPtr,
6946
+ mode,
6947
+ mPtr,
6948
+ FLAGS
6949
+ );
6950
+ } else {
6951
+ ok = !!this.pdfiumModule.EPDF_RenderAnnotBitmap(
6952
+ bitmapPtr,
6953
+ pageCtx.pagePtr,
6954
+ annotPtr,
6955
+ mode,
6956
+ mPtr,
6957
+ FLAGS
6958
+ );
6959
+ }
6398
6960
  } finally {
6399
6961
  this.memoryManager.free(mPtr);
6400
6962
  this.pdfiumModule.FPDFBitmap_Destroy(bitmapPtr);
@@ -7104,7 +7666,7 @@ class PdfiumNative {
7104
7666
  right: 0,
7105
7667
  bottom: 0
7106
7668
  };
7107
- if (this.pdfiumModule.FPDFAnnot_GetRect(annotationPtr, pageRectPtr)) {
7669
+ if (this.pdfiumModule.EPDFAnnot_GetRect(annotationPtr, pageRectPtr)) {
7108
7670
  pageRect.left = this.pdfiumModule.pdfium.getValue(pageRectPtr, "float");
7109
7671
  pageRect.top = this.pdfiumModule.pdfium.getValue(pageRectPtr + 4, "float");
7110
7672
  pageRect.right = this.pdfiumModule.pdfium.getValue(pageRectPtr + 8, "float");
@@ -7629,11 +8191,11 @@ export {
7629
8191
  PdfiumErrorCode as P,
7630
8192
  RenderFlag as R,
7631
8193
  PdfiumNative as a,
7632
- readArrayBuffer as b,
7633
- createPdfiumEngine as c,
7634
- computeFormDrawParams as d,
7635
- createNodeFontLoader as e,
8194
+ createNodeFontLoader as b,
8195
+ computeFormDrawParams as c,
8196
+ createPdfiumEngine as d,
8197
+ readString as e,
7636
8198
  isValidCustomKey as i,
7637
- readString as r
8199
+ readArrayBuffer as r
7638
8200
  };
7639
- //# sourceMappingURL=direct-engine-D8HGqcIt.js.map
8201
+ //# sourceMappingURL=direct-engine-BmntIHbH.js.map