@embedpdf/engines 1.0.6 → 1.0.7
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.
- package/dist/index.cjs +368 -184
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +72 -21
- package/dist/index.js +369 -185
- package/dist/index.js.map +1 -1
- package/dist/pdfium-direct-engine.cjs +325 -177
- package/dist/pdfium-direct-engine.cjs.map +1 -1
- package/dist/pdfium-direct-engine.d.ts +69 -20
- package/dist/pdfium-direct-engine.js +326 -178
- package/dist/pdfium-direct-engine.js.map +1 -1
- package/dist/pdfium-worker-engine.cjs +31 -1
- package/dist/pdfium-worker-engine.cjs.map +1 -1
- package/dist/pdfium-worker-engine.d.ts +4 -2
- package/dist/pdfium-worker-engine.js +31 -1
- package/dist/pdfium-worker-engine.js.map +1 -1
- package/dist/pdfium.cjs +332 -178
- package/dist/pdfium.cjs.map +1 -1
- package/dist/pdfium.d.ts +69 -20
- package/dist/pdfium.js +333 -179
- package/dist/pdfium.js.map +1 -1
- package/dist/worker.cjs +30 -0
- package/dist/worker.cjs.map +1 -1
- package/dist/worker.d.ts +4 -2
- package/dist/worker.js +30 -0
- package/dist/worker.js.map +1 -1
- package/package.json +3 -3
package/dist/pdfium.cjs
CHANGED
|
@@ -917,6 +917,12 @@ class PdfiumEngine {
|
|
|
917
917
|
case models.PdfAnnotationSubtype.STAMP:
|
|
918
918
|
isSucceed = this.addStampContent(ctx.docPtr, page, pageCtx.pagePtr, annotationPtr, annotation.rect, annotation.contents);
|
|
919
919
|
break;
|
|
920
|
+
case models.PdfAnnotationSubtype.UNDERLINE:
|
|
921
|
+
case models.PdfAnnotationSubtype.STRIKEOUT:
|
|
922
|
+
case models.PdfAnnotationSubtype.SQUIGGLY:
|
|
923
|
+
case models.PdfAnnotationSubtype.HIGHLIGHT:
|
|
924
|
+
isSucceed = this.addTextMarkupContent(page, annotationPtr, annotation);
|
|
925
|
+
break;
|
|
920
926
|
}
|
|
921
927
|
if (!isSucceed) {
|
|
922
928
|
this.pdfiumModule.FPDFPage_RemoveAnnot(pageCtx.pagePtr, annotationPtr);
|
|
@@ -928,10 +934,101 @@ class PdfiumEngine {
|
|
|
928
934
|
});
|
|
929
935
|
}
|
|
930
936
|
this.pdfiumModule.FPDFPage_GenerateContent(pageCtx.pagePtr);
|
|
937
|
+
const annotId = this.pdfiumModule.FPDFPage_GetAnnotIndex(pageCtx.pagePtr, annotationPtr);
|
|
931
938
|
this.pdfiumModule.FPDFPage_CloseAnnot(annotationPtr);
|
|
932
939
|
pageCtx.release();
|
|
933
940
|
this.logger.perf(LOG_SOURCE$1, LOG_CATEGORY$1, `CreatePageAnnotation`, 'End', `${doc.id}-${page.index}`);
|
|
934
|
-
return
|
|
941
|
+
return annotId >= 0
|
|
942
|
+
? models.PdfTaskHelper.resolve(annotId)
|
|
943
|
+
: models.PdfTaskHelper.reject({
|
|
944
|
+
code: models.PdfErrorCode.CantCreateAnnot,
|
|
945
|
+
message: 'annotation created but index could not be determined',
|
|
946
|
+
});
|
|
947
|
+
}
|
|
948
|
+
/**
|
|
949
|
+
* Update an existing page annotation in-place
|
|
950
|
+
*
|
|
951
|
+
* • Locates the annot by page-local index (`annotation.id`)
|
|
952
|
+
* • Re-writes its /Rect and type-specific payload
|
|
953
|
+
* • Calls FPDFPage_GenerateContent so the new appearance is rendered
|
|
954
|
+
*
|
|
955
|
+
* @returns PdfTask<boolean> – true on success
|
|
956
|
+
*/
|
|
957
|
+
updatePageAnnotation(doc, page, annotation) {
|
|
958
|
+
this.logger.debug(LOG_SOURCE$1, LOG_CATEGORY$1, 'updatePageAnnotation', doc, page, annotation);
|
|
959
|
+
this.logger.perf(LOG_SOURCE$1, LOG_CATEGORY$1, 'UpdatePageAnnotation', 'Begin', `${doc.id}-${page.index}`);
|
|
960
|
+
const ctx = this.cache.getContext(doc.id);
|
|
961
|
+
if (!ctx) {
|
|
962
|
+
this.logger.perf(LOG_SOURCE$1, LOG_CATEGORY$1, 'UpdatePageAnnotation', 'End', `${doc.id}-${page.index}`);
|
|
963
|
+
return models.PdfTaskHelper.reject({
|
|
964
|
+
code: models.PdfErrorCode.DocNotOpen,
|
|
965
|
+
message: 'document does not open',
|
|
966
|
+
});
|
|
967
|
+
}
|
|
968
|
+
const pageCtx = ctx.acquirePage(page.index);
|
|
969
|
+
const annotPtr = this.pdfiumModule.FPDFPage_GetAnnot(pageCtx.pagePtr, annotation.id);
|
|
970
|
+
if (!annotPtr) {
|
|
971
|
+
pageCtx.release();
|
|
972
|
+
this.logger.perf(LOG_SOURCE$1, LOG_CATEGORY$1, 'UpdatePageAnnotation', 'End', `${doc.id}-${page.index}`);
|
|
973
|
+
return models.PdfTaskHelper.reject({ code: models.PdfErrorCode.NotFound, message: 'annotation not found' });
|
|
974
|
+
}
|
|
975
|
+
/* 1 ── (re)set bounding-box ────────────────────────────────────────────── */
|
|
976
|
+
if (!this.setPageAnnoRect(page, pageCtx.pagePtr, annotPtr, annotation.rect)) {
|
|
977
|
+
this.pdfiumModule.FPDFPage_CloseAnnot(annotPtr);
|
|
978
|
+
pageCtx.release();
|
|
979
|
+
this.logger.perf(LOG_SOURCE$1, LOG_CATEGORY$1, 'UpdatePageAnnotation', 'End', `${doc.id}-${page.index}`);
|
|
980
|
+
return models.PdfTaskHelper.reject({
|
|
981
|
+
code: models.PdfErrorCode.CantSetAnnotRect,
|
|
982
|
+
message: 'failed to move annotation',
|
|
983
|
+
});
|
|
984
|
+
}
|
|
985
|
+
/* 2 ── wipe previous payload and rebuild fresh one ─────────────────────── */
|
|
986
|
+
let ok = false;
|
|
987
|
+
switch (annotation.type) {
|
|
988
|
+
/* ── Ink ─────────────────────────────────────────────────────────────── */
|
|
989
|
+
case models.PdfAnnotationSubtype.INK: {
|
|
990
|
+
/* clear every existing stroke first */
|
|
991
|
+
if (!this.pdfiumModule.FPDFAnnot_RemoveInkList(annotPtr))
|
|
992
|
+
break;
|
|
993
|
+
ok = this.addInkStroke(page, pageCtx.pagePtr, annotPtr, annotation.inkList);
|
|
994
|
+
break;
|
|
995
|
+
}
|
|
996
|
+
/* ── Stamp ───────────────────────────────────────────────────────────── */
|
|
997
|
+
case models.PdfAnnotationSubtype.STAMP: {
|
|
998
|
+
/* drop every page-object inside the annot */
|
|
999
|
+
for (let i = this.pdfiumModule.FPDFAnnot_GetObjectCount(annotPtr) - 1; i >= 0; i--) {
|
|
1000
|
+
this.pdfiumModule.FPDFAnnot_RemoveObject(annotPtr, i);
|
|
1001
|
+
}
|
|
1002
|
+
ok = this.addStampContent(ctx.docPtr, page, pageCtx.pagePtr, annotPtr, annotation.rect, annotation.contents);
|
|
1003
|
+
break;
|
|
1004
|
+
}
|
|
1005
|
+
/* ── Text-markup family ──────────────────────────────────────────────── */
|
|
1006
|
+
case models.PdfAnnotationSubtype.HIGHLIGHT:
|
|
1007
|
+
case models.PdfAnnotationSubtype.UNDERLINE:
|
|
1008
|
+
case models.PdfAnnotationSubtype.STRIKEOUT:
|
|
1009
|
+
case models.PdfAnnotationSubtype.SQUIGGLY: {
|
|
1010
|
+
/* replace quad-points / colour / strings in one go */
|
|
1011
|
+
ok = this.addTextMarkupContent(page, annotPtr, annotation, true);
|
|
1012
|
+
break;
|
|
1013
|
+
}
|
|
1014
|
+
/* ── Unsupported edits – fall through to error ───────────────────────── */
|
|
1015
|
+
default:
|
|
1016
|
+
ok = false;
|
|
1017
|
+
}
|
|
1018
|
+
/* 3 ── regenerate appearance if payload was changed ───────────────────── */
|
|
1019
|
+
if (ok) {
|
|
1020
|
+
this.pdfiumModule.FPDFPage_GenerateContent(pageCtx.pagePtr);
|
|
1021
|
+
}
|
|
1022
|
+
/* 4 ── tidy-up native handles ──────────────────────────────────────────── */
|
|
1023
|
+
this.pdfiumModule.FPDFPage_CloseAnnot(annotPtr);
|
|
1024
|
+
pageCtx.release();
|
|
1025
|
+
this.logger.perf(LOG_SOURCE$1, LOG_CATEGORY$1, 'UpdatePageAnnotation', 'End', `${doc.id}-${page.index}`);
|
|
1026
|
+
return ok
|
|
1027
|
+
? models.PdfTaskHelper.resolve(true)
|
|
1028
|
+
: models.PdfTaskHelper.reject({
|
|
1029
|
+
code: models.PdfErrorCode.CantSetAnnotContent,
|
|
1030
|
+
message: 'failed to update annotation',
|
|
1031
|
+
});
|
|
935
1032
|
}
|
|
936
1033
|
/**
|
|
937
1034
|
* {@inheritDoc @embedpdf/models!PdfEngine.transformPageAnnotation}
|
|
@@ -1650,6 +1747,36 @@ class PdfiumEngine {
|
|
|
1650
1747
|
}
|
|
1651
1748
|
return true;
|
|
1652
1749
|
}
|
|
1750
|
+
/**
|
|
1751
|
+
* Add highlight content to annotation
|
|
1752
|
+
* @param page - page info
|
|
1753
|
+
* @param annotationPtr - pointer to highlight annotation
|
|
1754
|
+
* @param annotation - highlight annotation
|
|
1755
|
+
* @returns whether highlight content is added to annotation
|
|
1756
|
+
*
|
|
1757
|
+
* @private
|
|
1758
|
+
*/
|
|
1759
|
+
addTextMarkupContent(page, annotationPtr, annotation, shouldClearAP = false) {
|
|
1760
|
+
if (!this.syncQuadPointsAnno(page, annotationPtr, annotation.segmentRects)) {
|
|
1761
|
+
return false;
|
|
1762
|
+
}
|
|
1763
|
+
if (!this.setAnnotString(annotationPtr, 'Contents', annotation.contents ?? '')) {
|
|
1764
|
+
return false;
|
|
1765
|
+
}
|
|
1766
|
+
if (!this.setAnnotString(annotationPtr, 'T', annotation.author || '')) {
|
|
1767
|
+
return false;
|
|
1768
|
+
}
|
|
1769
|
+
if (!this.setAnnotString(annotationPtr, 'M', models.dateToPdfDate(annotation.modified))) {
|
|
1770
|
+
return false;
|
|
1771
|
+
}
|
|
1772
|
+
if (!this.setAnnotationColor(annotationPtr, {
|
|
1773
|
+
color: annotation.color ?? '#FFFF00',
|
|
1774
|
+
opacity: annotation.opacity ?? 1,
|
|
1775
|
+
}, shouldClearAP, 0)) {
|
|
1776
|
+
return false;
|
|
1777
|
+
}
|
|
1778
|
+
return true;
|
|
1779
|
+
}
|
|
1653
1780
|
/**
|
|
1654
1781
|
* Add contents to stamp annotation
|
|
1655
1782
|
* @param docPtr - pointer to pdf document object
|
|
@@ -2272,8 +2399,6 @@ class PdfiumEngine {
|
|
|
2272
2399
|
annotation = this.readPdfCaretAnno(page, pageCtx.pagePtr, annotationPtr, index);
|
|
2273
2400
|
}
|
|
2274
2401
|
break;
|
|
2275
|
-
case models.PdfAnnotationSubtype.POPUP:
|
|
2276
|
-
break;
|
|
2277
2402
|
default:
|
|
2278
2403
|
{
|
|
2279
2404
|
annotation = this.readPdfAnno(page, pageCtx.pagePtr, subType, annotationPtr, index);
|
|
@@ -2420,15 +2545,35 @@ class PdfiumEngine {
|
|
|
2420
2545
|
*
|
|
2421
2546
|
* @param annotationPtr - pointer to an `FPDF_ANNOTATION`
|
|
2422
2547
|
* @param fallback - colour to use when the PDF stores no tint at all
|
|
2423
|
-
* @returns
|
|
2548
|
+
* @returns WebAlphaColor with hex color and opacity (0-1)
|
|
2424
2549
|
*
|
|
2425
2550
|
* @private
|
|
2426
2551
|
*/
|
|
2427
2552
|
resolveAnnotationColor(annotationPtr, fallback = { red: 255, green: 245, blue: 155, alpha: 255 }) {
|
|
2428
|
-
|
|
2553
|
+
const pdfColor = this.readAnnotationColor(annotationPtr) ?? // 1 – /C entry
|
|
2429
2554
|
this.colorFromAppearance(annotationPtr) ?? // 2 – AP stream walk
|
|
2430
|
-
fallback // 3 – default
|
|
2431
|
-
);
|
|
2555
|
+
fallback; // 3 – default
|
|
2556
|
+
return models.pdfAlphaColorToWebAlphaColor(pdfColor);
|
|
2557
|
+
}
|
|
2558
|
+
/**
|
|
2559
|
+
* Set the fill/stroke colour for a **Highlight / Underline / StrikeOut / Squiggly** markup annotation.
|
|
2560
|
+
*
|
|
2561
|
+
* @param annotationPtr - pointer to the annotation whose colour is being set
|
|
2562
|
+
* @param webAlphaColor - WebAlphaColor with hex color and opacity (0-1)
|
|
2563
|
+
* @param shouldClearAP - whether to clear the /AP entry
|
|
2564
|
+
* @param which - which colour to set (0 = fill, 1 = stroke)
|
|
2565
|
+
* @returns `true` if the operation was successful
|
|
2566
|
+
*
|
|
2567
|
+
* @private
|
|
2568
|
+
*/
|
|
2569
|
+
setAnnotationColor(annotationPtr, webAlphaColor, shouldClearAP = false, which = 0) {
|
|
2570
|
+
const pdfAlphaColor = models.webAlphaColorToPdfAlphaColor(webAlphaColor);
|
|
2571
|
+
if (shouldClearAP) {
|
|
2572
|
+
// NULL wide-string → remove the /AP entry
|
|
2573
|
+
this.pdfiumModule.FPDFAnnot_SetAP(annotationPtr, models.AppearanceMode.Normal,
|
|
2574
|
+
/* FPDF_WIDESTRING = */ 0);
|
|
2575
|
+
}
|
|
2576
|
+
return this.pdfiumModule.FPDFAnnot_SetColor(annotationPtr, which, pdfAlphaColor.red & 0xff, pdfAlphaColor.green & 0xff, pdfAlphaColor.blue & 0xff, (pdfAlphaColor.alpha ?? 255) & 0xff);
|
|
2432
2577
|
}
|
|
2433
2578
|
/**
|
|
2434
2579
|
* Read `/QuadPoints` from any annotation and convert each quadrilateral to
|
|
@@ -2441,11 +2586,11 @@ class PdfiumEngine {
|
|
|
2441
2586
|
*
|
|
2442
2587
|
* @param page - logical page info object (`PdfPageObject`)
|
|
2443
2588
|
* @param annotationPtr - pointer to the annotation whose quads are needed
|
|
2444
|
-
* @returns Array of `
|
|
2589
|
+
* @returns Array of `Rect` objects (`[]` if the annotation has no quads)
|
|
2445
2590
|
*
|
|
2446
2591
|
* @private
|
|
2447
2592
|
*/
|
|
2448
|
-
|
|
2593
|
+
getQuadPointsAnno(page, annotationPtr) {
|
|
2449
2594
|
const quadCount = this.pdfiumModule.FPDFAnnot_CountAttachmentPoints(annotationPtr);
|
|
2450
2595
|
if (quadCount === 0)
|
|
2451
2596
|
return [];
|
|
@@ -2472,7 +2617,60 @@ class PdfiumEngine {
|
|
|
2472
2617
|
}
|
|
2473
2618
|
this.free(quadPtr);
|
|
2474
2619
|
}
|
|
2475
|
-
return quads;
|
|
2620
|
+
return quads.map(models.quadToRect);
|
|
2621
|
+
}
|
|
2622
|
+
/**
|
|
2623
|
+
* Set the quadrilaterals for a **Highlight / Underline / StrikeOut / Squiggly** markup annotation.
|
|
2624
|
+
*
|
|
2625
|
+
* @param page - logical page info object (`PdfPageObject`)
|
|
2626
|
+
* @param annotationPtr - pointer to the annotation whose quads are needed
|
|
2627
|
+
* @param rects - array of `Rect` objects (`[]` if the annotation has no quads)
|
|
2628
|
+
* @returns `true` if the operation was successful
|
|
2629
|
+
*
|
|
2630
|
+
* @private
|
|
2631
|
+
*/
|
|
2632
|
+
syncQuadPointsAnno(page, annotPtr, rects) {
|
|
2633
|
+
const FS_QUADPOINTSF_SIZE = 8 * 4; // eight floats, 32 bytes
|
|
2634
|
+
const pdf = this.pdfiumModule.pdfium;
|
|
2635
|
+
const count = this.pdfiumModule.FPDFAnnot_CountAttachmentPoints(annotPtr);
|
|
2636
|
+
const buf = this.malloc(FS_QUADPOINTSF_SIZE);
|
|
2637
|
+
/** write one quad into `buf` in annotation space */
|
|
2638
|
+
const writeQuad = (r) => {
|
|
2639
|
+
const q = models.rectToQuad(r); // TL, TR, BR, BL
|
|
2640
|
+
const p1 = this.convertDevicePointToPagePoint(page, q.p1);
|
|
2641
|
+
const p2 = this.convertDevicePointToPagePoint(page, q.p2);
|
|
2642
|
+
const p3 = this.convertDevicePointToPagePoint(page, q.p3); // BR
|
|
2643
|
+
const p4 = this.convertDevicePointToPagePoint(page, q.p4); // BL
|
|
2644
|
+
// PDF QuadPoints order: BL, BR, TL, TR (bottom-left, bottom-right, top-left, top-right)
|
|
2645
|
+
pdf.setValue(buf + 0, p1.x, 'float'); // BL (bottom-left)
|
|
2646
|
+
pdf.setValue(buf + 4, p1.y, 'float');
|
|
2647
|
+
pdf.setValue(buf + 8, p2.x, 'float'); // BR (bottom-right)
|
|
2648
|
+
pdf.setValue(buf + 12, p2.y, 'float');
|
|
2649
|
+
pdf.setValue(buf + 16, p4.x, 'float'); // TL (top-left)
|
|
2650
|
+
pdf.setValue(buf + 20, p4.y, 'float');
|
|
2651
|
+
pdf.setValue(buf + 24, p3.x, 'float'); // TR (top-right)
|
|
2652
|
+
pdf.setValue(buf + 28, p3.y, 'float');
|
|
2653
|
+
};
|
|
2654
|
+
/* ----------------------------------------------------------------------- */
|
|
2655
|
+
/* 1. overwrite the quads that already exist */
|
|
2656
|
+
const min = Math.min(count, rects.length);
|
|
2657
|
+
for (let i = 0; i < min; i++) {
|
|
2658
|
+
writeQuad(rects[i]);
|
|
2659
|
+
if (!this.pdfiumModule.FPDFAnnot_SetAttachmentPoints(annotPtr, i, buf)) {
|
|
2660
|
+
this.free(buf);
|
|
2661
|
+
return false;
|
|
2662
|
+
}
|
|
2663
|
+
}
|
|
2664
|
+
/* 2. append new quads if rects.length > count */
|
|
2665
|
+
for (let i = count; i < rects.length; i++) {
|
|
2666
|
+
writeQuad(rects[i]);
|
|
2667
|
+
if (!this.pdfiumModule.FPDFAnnot_AppendAttachmentPoints(annotPtr, buf)) {
|
|
2668
|
+
this.free(buf);
|
|
2669
|
+
return false;
|
|
2670
|
+
}
|
|
2671
|
+
}
|
|
2672
|
+
this.free(buf);
|
|
2673
|
+
return true;
|
|
2476
2674
|
}
|
|
2477
2675
|
/**
|
|
2478
2676
|
* Read pdf text annotation
|
|
@@ -2485,30 +2683,23 @@ class PdfiumEngine {
|
|
|
2485
2683
|
* @private
|
|
2486
2684
|
*/
|
|
2487
2685
|
readPdfTextAnno(page, pagePtr, annotationPtr, index) {
|
|
2488
|
-
const appearances = this.readPageAnnoAppearanceStreams(annotationPtr);
|
|
2489
2686
|
const annoRect = this.readPageAnnoRect(annotationPtr);
|
|
2490
2687
|
const rect = this.convertPageRectToDeviceRect(page, pagePtr, annoRect);
|
|
2491
2688
|
const author = this.getAnnotString(annotationPtr, 'T');
|
|
2492
2689
|
const modifiedRaw = this.getAnnotString(annotationPtr, 'M');
|
|
2493
|
-
const modified =
|
|
2690
|
+
const modified = models.pdfDateToDate(modifiedRaw);
|
|
2494
2691
|
const contents = this.getAnnotString(annotationPtr, 'Contents') || '';
|
|
2495
2692
|
const state = this.getAnnotString(annotationPtr, 'State');
|
|
2496
2693
|
const stateModel = this.getAnnotString(annotationPtr, 'StateModel');
|
|
2497
|
-
const
|
|
2694
|
+
const webAlphaColor = this.resolveAnnotationColor(annotationPtr);
|
|
2498
2695
|
const inReplyToId = this.getInReplyToId(pagePtr, annotationPtr);
|
|
2499
|
-
const popup = !inReplyToId
|
|
2500
|
-
? this.readPdfAnnoLinkedPopup(page, pagePtr, annotationPtr, index)
|
|
2501
|
-
: undefined;
|
|
2502
2696
|
return {
|
|
2503
|
-
status: models.PdfAnnotationObjectStatus.Committed,
|
|
2504
2697
|
pageIndex: page.index,
|
|
2505
2698
|
id: index,
|
|
2506
2699
|
type: models.PdfAnnotationSubtype.TEXT,
|
|
2507
2700
|
contents,
|
|
2508
|
-
|
|
2701
|
+
...webAlphaColor,
|
|
2509
2702
|
rect,
|
|
2510
|
-
popup,
|
|
2511
|
-
appearances,
|
|
2512
2703
|
inReplyToId,
|
|
2513
2704
|
author,
|
|
2514
2705
|
modified,
|
|
@@ -2527,16 +2718,13 @@ class PdfiumEngine {
|
|
|
2527
2718
|
* @private
|
|
2528
2719
|
*/
|
|
2529
2720
|
readPdfFreeTextAnno(page, pagePtr, annotationPtr, index) {
|
|
2530
|
-
const appearances = this.readPageAnnoAppearanceStreams(annotationPtr);
|
|
2531
2721
|
const annoRect = this.readPageAnnoRect(annotationPtr);
|
|
2532
2722
|
const rect = this.convertPageRectToDeviceRect(page, pagePtr, annoRect);
|
|
2533
2723
|
const contents = this.getAnnotString(annotationPtr, 'Contents') || '';
|
|
2534
2724
|
const author = this.getAnnotString(annotationPtr, 'T');
|
|
2535
2725
|
const modifiedRaw = this.getAnnotString(annotationPtr, 'M');
|
|
2536
|
-
const modified =
|
|
2537
|
-
const popup = this.readPdfAnnoLinkedPopup(page, pagePtr, annotationPtr, index);
|
|
2726
|
+
const modified = models.pdfDateToDate(modifiedRaw);
|
|
2538
2727
|
return {
|
|
2539
|
-
status: models.PdfAnnotationObjectStatus.Committed,
|
|
2540
2728
|
pageIndex: page.index,
|
|
2541
2729
|
id: index,
|
|
2542
2730
|
type: models.PdfAnnotationSubtype.FREETEXT,
|
|
@@ -2544,8 +2732,6 @@ class PdfiumEngine {
|
|
|
2544
2732
|
author,
|
|
2545
2733
|
modified,
|
|
2546
2734
|
rect,
|
|
2547
|
-
popup,
|
|
2548
|
-
appearances,
|
|
2549
2735
|
};
|
|
2550
2736
|
}
|
|
2551
2737
|
/**
|
|
@@ -2565,13 +2751,12 @@ class PdfiumEngine {
|
|
|
2565
2751
|
if (!linkPtr) {
|
|
2566
2752
|
return;
|
|
2567
2753
|
}
|
|
2568
|
-
const appearances = this.readPageAnnoAppearanceStreams(annotationPtr);
|
|
2569
2754
|
const annoRect = this.readPageAnnoRect(annotationPtr);
|
|
2570
2755
|
const { left, top, right, bottom } = annoRect;
|
|
2571
2756
|
const rect = this.convertPageRectToDeviceRect(page, pagePtr, annoRect);
|
|
2572
2757
|
const author = this.getAnnotString(annotationPtr, 'T');
|
|
2573
2758
|
const modifiedRaw = this.getAnnotString(annotationPtr, 'M');
|
|
2574
|
-
const modified =
|
|
2759
|
+
const modified = models.pdfDateToDate(modifiedRaw);
|
|
2575
2760
|
const utf16Length = this.pdfiumModule.FPDFText_GetBoundedText(textPagePtr, left, top, right, bottom, 0, 0);
|
|
2576
2761
|
const bytesCount = (utf16Length + 1) * 2; // include NIL
|
|
2577
2762
|
const textBufferPtr = this.malloc(bytesCount);
|
|
@@ -2583,17 +2768,13 @@ class PdfiumEngine {
|
|
|
2583
2768
|
}, () => {
|
|
2584
2769
|
return this.pdfiumModule.FPDFLink_GetDest(docPtr, linkPtr);
|
|
2585
2770
|
});
|
|
2586
|
-
const popup = this.readPdfAnnoLinkedPopup(page, pagePtr, annotationPtr, index);
|
|
2587
2771
|
return {
|
|
2588
|
-
status: models.PdfAnnotationObjectStatus.Committed,
|
|
2589
2772
|
pageIndex: page.index,
|
|
2590
2773
|
id: index,
|
|
2591
2774
|
type: models.PdfAnnotationSubtype.LINK,
|
|
2592
2775
|
text,
|
|
2593
2776
|
target,
|
|
2594
2777
|
rect,
|
|
2595
|
-
popup,
|
|
2596
|
-
appearances,
|
|
2597
2778
|
author,
|
|
2598
2779
|
modified,
|
|
2599
2780
|
};
|
|
@@ -2610,23 +2791,18 @@ class PdfiumEngine {
|
|
|
2610
2791
|
* @private
|
|
2611
2792
|
*/
|
|
2612
2793
|
readPdfWidgetAnno(page, pagePtr, annotationPtr, formHandle, index) {
|
|
2613
|
-
const appearances = this.readPageAnnoAppearanceStreams(annotationPtr);
|
|
2614
2794
|
const pageRect = this.readPageAnnoRect(annotationPtr);
|
|
2615
2795
|
const rect = this.convertPageRectToDeviceRect(page, pagePtr, pageRect);
|
|
2616
2796
|
const author = this.getAnnotString(annotationPtr, 'T');
|
|
2617
2797
|
const modifiedRaw = this.getAnnotString(annotationPtr, 'M');
|
|
2618
|
-
const modified =
|
|
2619
|
-
const popup = this.readPdfAnnoLinkedPopup(page, pagePtr, annotationPtr, index);
|
|
2798
|
+
const modified = models.pdfDateToDate(modifiedRaw);
|
|
2620
2799
|
const field = this.readPdfWidgetAnnoField(formHandle, annotationPtr);
|
|
2621
2800
|
return {
|
|
2622
|
-
status: models.PdfAnnotationObjectStatus.Committed,
|
|
2623
2801
|
pageIndex: page.index,
|
|
2624
2802
|
id: index,
|
|
2625
2803
|
type: models.PdfAnnotationSubtype.WIDGET,
|
|
2626
2804
|
rect,
|
|
2627
2805
|
field,
|
|
2628
|
-
popup,
|
|
2629
|
-
appearances,
|
|
2630
2806
|
author,
|
|
2631
2807
|
modified,
|
|
2632
2808
|
};
|
|
@@ -2642,21 +2818,16 @@ class PdfiumEngine {
|
|
|
2642
2818
|
* @private
|
|
2643
2819
|
*/
|
|
2644
2820
|
readPdfFileAttachmentAnno(page, pagePtr, annotationPtr, index) {
|
|
2645
|
-
const appearances = this.readPageAnnoAppearanceStreams(annotationPtr);
|
|
2646
2821
|
const pageRect = this.readPageAnnoRect(annotationPtr);
|
|
2647
2822
|
const rect = this.convertPageRectToDeviceRect(page, pagePtr, pageRect);
|
|
2648
2823
|
const author = this.getAnnotString(annotationPtr, 'T');
|
|
2649
2824
|
const modifiedRaw = this.getAnnotString(annotationPtr, 'M');
|
|
2650
|
-
const modified =
|
|
2651
|
-
const popup = this.readPdfAnnoLinkedPopup(page, pagePtr, annotationPtr, index);
|
|
2825
|
+
const modified = models.pdfDateToDate(modifiedRaw);
|
|
2652
2826
|
return {
|
|
2653
|
-
status: models.PdfAnnotationObjectStatus.Committed,
|
|
2654
2827
|
pageIndex: page.index,
|
|
2655
2828
|
id: index,
|
|
2656
2829
|
type: models.PdfAnnotationSubtype.FILEATTACHMENT,
|
|
2657
2830
|
rect,
|
|
2658
|
-
popup,
|
|
2659
|
-
appearances,
|
|
2660
2831
|
author,
|
|
2661
2832
|
modified,
|
|
2662
2833
|
};
|
|
@@ -2672,13 +2843,11 @@ class PdfiumEngine {
|
|
|
2672
2843
|
* @private
|
|
2673
2844
|
*/
|
|
2674
2845
|
readPdfInkAnno(page, pagePtr, annotationPtr, index) {
|
|
2675
|
-
const appearances = this.readPageAnnoAppearanceStreams(annotationPtr);
|
|
2676
2846
|
const pageRect = this.readPageAnnoRect(annotationPtr);
|
|
2677
2847
|
const rect = this.convertPageRectToDeviceRect(page, pagePtr, pageRect);
|
|
2678
2848
|
const author = this.getAnnotString(annotationPtr, 'T');
|
|
2679
2849
|
const modifiedRaw = this.getAnnotString(annotationPtr, 'M');
|
|
2680
|
-
const modified =
|
|
2681
|
-
const popup = this.readPdfAnnoLinkedPopup(page, pagePtr, annotationPtr, index);
|
|
2850
|
+
const modified = models.pdfDateToDate(modifiedRaw);
|
|
2682
2851
|
const inkList = [];
|
|
2683
2852
|
const count = this.pdfiumModule.FPDFAnnot_GetInkListCount(annotationPtr);
|
|
2684
2853
|
for (let i = 0; i < count; i++) {
|
|
@@ -2702,14 +2871,11 @@ class PdfiumEngine {
|
|
|
2702
2871
|
inkList.push({ points });
|
|
2703
2872
|
}
|
|
2704
2873
|
return {
|
|
2705
|
-
status: models.PdfAnnotationObjectStatus.Committed,
|
|
2706
2874
|
pageIndex: page.index,
|
|
2707
2875
|
id: index,
|
|
2708
2876
|
type: models.PdfAnnotationSubtype.INK,
|
|
2709
2877
|
rect,
|
|
2710
|
-
popup,
|
|
2711
2878
|
inkList,
|
|
2712
|
-
appearances,
|
|
2713
2879
|
author,
|
|
2714
2880
|
modified,
|
|
2715
2881
|
};
|
|
@@ -2725,23 +2891,18 @@ class PdfiumEngine {
|
|
|
2725
2891
|
* @private
|
|
2726
2892
|
*/
|
|
2727
2893
|
readPdfPolygonAnno(page, pagePtr, annotationPtr, index) {
|
|
2728
|
-
const appearances = this.readPageAnnoAppearanceStreams(annotationPtr);
|
|
2729
2894
|
const pageRect = this.readPageAnnoRect(annotationPtr);
|
|
2730
2895
|
const rect = this.convertPageRectToDeviceRect(page, pagePtr, pageRect);
|
|
2731
2896
|
const author = this.getAnnotString(annotationPtr, 'T');
|
|
2732
2897
|
const modifiedRaw = this.getAnnotString(annotationPtr, 'M');
|
|
2733
|
-
const modified =
|
|
2734
|
-
const popup = this.readPdfAnnoLinkedPopup(page, pagePtr, annotationPtr, index);
|
|
2898
|
+
const modified = models.pdfDateToDate(modifiedRaw);
|
|
2735
2899
|
const vertices = this.readPdfAnnoVertices(page, pagePtr, annotationPtr);
|
|
2736
2900
|
return {
|
|
2737
|
-
status: models.PdfAnnotationObjectStatus.Committed,
|
|
2738
2901
|
pageIndex: page.index,
|
|
2739
2902
|
id: index,
|
|
2740
2903
|
type: models.PdfAnnotationSubtype.POLYGON,
|
|
2741
2904
|
rect,
|
|
2742
|
-
popup,
|
|
2743
2905
|
vertices,
|
|
2744
|
-
appearances,
|
|
2745
2906
|
author,
|
|
2746
2907
|
modified,
|
|
2747
2908
|
};
|
|
@@ -2757,23 +2918,18 @@ class PdfiumEngine {
|
|
|
2757
2918
|
* @private
|
|
2758
2919
|
*/
|
|
2759
2920
|
readPdfPolylineAnno(page, pagePtr, annotationPtr, index) {
|
|
2760
|
-
const appearances = this.readPageAnnoAppearanceStreams(annotationPtr);
|
|
2761
2921
|
const pageRect = this.readPageAnnoRect(annotationPtr);
|
|
2762
2922
|
const rect = this.convertPageRectToDeviceRect(page, pagePtr, pageRect);
|
|
2763
2923
|
const author = this.getAnnotString(annotationPtr, 'T');
|
|
2764
2924
|
const modifiedRaw = this.getAnnotString(annotationPtr, 'M');
|
|
2765
|
-
const modified =
|
|
2766
|
-
const popup = this.readPdfAnnoLinkedPopup(page, pagePtr, annotationPtr, index);
|
|
2925
|
+
const modified = models.pdfDateToDate(modifiedRaw);
|
|
2767
2926
|
const vertices = this.readPdfAnnoVertices(page, pagePtr, annotationPtr);
|
|
2768
2927
|
return {
|
|
2769
|
-
status: models.PdfAnnotationObjectStatus.Committed,
|
|
2770
2928
|
pageIndex: page.index,
|
|
2771
2929
|
id: index,
|
|
2772
2930
|
type: models.PdfAnnotationSubtype.POLYLINE,
|
|
2773
2931
|
rect,
|
|
2774
|
-
popup,
|
|
2775
2932
|
vertices,
|
|
2776
|
-
appearances,
|
|
2777
2933
|
author,
|
|
2778
2934
|
modified,
|
|
2779
2935
|
};
|
|
@@ -2789,13 +2945,11 @@ class PdfiumEngine {
|
|
|
2789
2945
|
* @private
|
|
2790
2946
|
*/
|
|
2791
2947
|
readPdfLineAnno(page, pagePtr, annotationPtr, index) {
|
|
2792
|
-
const appearances = this.readPageAnnoAppearanceStreams(annotationPtr);
|
|
2793
2948
|
const pageRect = this.readPageAnnoRect(annotationPtr);
|
|
2794
2949
|
const rect = this.convertPageRectToDeviceRect(page, pagePtr, pageRect);
|
|
2795
2950
|
const author = this.getAnnotString(annotationPtr, 'T');
|
|
2796
2951
|
const modifiedRaw = this.getAnnotString(annotationPtr, 'M');
|
|
2797
|
-
const modified =
|
|
2798
|
-
const popup = this.readPdfAnnoLinkedPopup(page, pagePtr, annotationPtr, index);
|
|
2952
|
+
const modified = models.pdfDateToDate(modifiedRaw);
|
|
2799
2953
|
const startPointPtr = this.malloc(8);
|
|
2800
2954
|
const endPointPtr = this.malloc(8);
|
|
2801
2955
|
this.pdfiumModule.FPDFAnnot_GetLine(annotationPtr, startPointPtr, endPointPtr);
|
|
@@ -2814,15 +2968,12 @@ class PdfiumEngine {
|
|
|
2814
2968
|
this.free(startPointPtr);
|
|
2815
2969
|
this.free(endPointPtr);
|
|
2816
2970
|
return {
|
|
2817
|
-
status: models.PdfAnnotationObjectStatus.Committed,
|
|
2818
2971
|
pageIndex: page.index,
|
|
2819
2972
|
id: index,
|
|
2820
2973
|
type: models.PdfAnnotationSubtype.LINE,
|
|
2821
2974
|
rect,
|
|
2822
|
-
popup,
|
|
2823
2975
|
startPoint,
|
|
2824
2976
|
endPoint,
|
|
2825
|
-
appearances,
|
|
2826
2977
|
author,
|
|
2827
2978
|
modified,
|
|
2828
2979
|
};
|
|
@@ -2838,25 +2989,22 @@ class PdfiumEngine {
|
|
|
2838
2989
|
* @private
|
|
2839
2990
|
*/
|
|
2840
2991
|
readPdfHighlightAnno(page, pagePtr, annotationPtr, index) {
|
|
2841
|
-
const appearances = this.readPageAnnoAppearanceStreams(annotationPtr);
|
|
2842
2992
|
const pageRect = this.readPageAnnoRect(annotationPtr);
|
|
2843
2993
|
const rect = this.convertPageRectToDeviceRect(page, pagePtr, pageRect);
|
|
2844
|
-
const
|
|
2845
|
-
const
|
|
2846
|
-
const popup = this.readPdfAnnoLinkedPopup(page, pagePtr, annotationPtr, index);
|
|
2994
|
+
const segmentRects = this.getQuadPointsAnno(page, annotationPtr);
|
|
2995
|
+
const webAlphaColor = this.resolveAnnotationColor(annotationPtr);
|
|
2847
2996
|
const author = this.getAnnotString(annotationPtr, 'T');
|
|
2848
2997
|
const modifiedRaw = this.getAnnotString(annotationPtr, 'M');
|
|
2849
|
-
const modified =
|
|
2998
|
+
const modified = models.pdfDateToDate(modifiedRaw);
|
|
2999
|
+
const contents = this.getAnnotString(annotationPtr, 'Contents') || '';
|
|
2850
3000
|
return {
|
|
2851
|
-
status: models.PdfAnnotationObjectStatus.Committed,
|
|
2852
3001
|
pageIndex: page.index,
|
|
2853
3002
|
id: index,
|
|
2854
3003
|
type: models.PdfAnnotationSubtype.HIGHLIGHT,
|
|
2855
3004
|
rect,
|
|
2856
|
-
|
|
2857
|
-
|
|
2858
|
-
|
|
2859
|
-
color,
|
|
3005
|
+
contents,
|
|
3006
|
+
segmentRects,
|
|
3007
|
+
...webAlphaColor,
|
|
2860
3008
|
author,
|
|
2861
3009
|
modified,
|
|
2862
3010
|
};
|
|
@@ -2872,21 +3020,22 @@ class PdfiumEngine {
|
|
|
2872
3020
|
* @private
|
|
2873
3021
|
*/
|
|
2874
3022
|
readPdfUnderlineAnno(page, pagePtr, annotationPtr, index) {
|
|
2875
|
-
const appearances = this.readPageAnnoAppearanceStreams(annotationPtr);
|
|
2876
3023
|
const pageRect = this.readPageAnnoRect(annotationPtr);
|
|
2877
3024
|
const rect = this.convertPageRectToDeviceRect(page, pagePtr, pageRect);
|
|
2878
3025
|
const author = this.getAnnotString(annotationPtr, 'T');
|
|
2879
3026
|
const modifiedRaw = this.getAnnotString(annotationPtr, 'M');
|
|
2880
|
-
const modified =
|
|
2881
|
-
const
|
|
3027
|
+
const modified = models.pdfDateToDate(modifiedRaw);
|
|
3028
|
+
const segmentRects = this.getQuadPointsAnno(page, annotationPtr);
|
|
3029
|
+
const contents = this.getAnnotString(annotationPtr, 'Contents') || '';
|
|
3030
|
+
const webAlphaColor = this.resolveAnnotationColor(annotationPtr);
|
|
2882
3031
|
return {
|
|
2883
|
-
status: models.PdfAnnotationObjectStatus.Committed,
|
|
2884
3032
|
pageIndex: page.index,
|
|
2885
3033
|
id: index,
|
|
2886
3034
|
type: models.PdfAnnotationSubtype.UNDERLINE,
|
|
2887
3035
|
rect,
|
|
2888
|
-
|
|
2889
|
-
|
|
3036
|
+
contents,
|
|
3037
|
+
segmentRects,
|
|
3038
|
+
...webAlphaColor,
|
|
2890
3039
|
author,
|
|
2891
3040
|
modified,
|
|
2892
3041
|
};
|
|
@@ -2902,21 +3051,22 @@ class PdfiumEngine {
|
|
|
2902
3051
|
* @private
|
|
2903
3052
|
*/
|
|
2904
3053
|
readPdfStrikeOutAnno(page, pagePtr, annotationPtr, index) {
|
|
2905
|
-
const appearances = this.readPageAnnoAppearanceStreams(annotationPtr);
|
|
2906
3054
|
const pageRect = this.readPageAnnoRect(annotationPtr);
|
|
2907
3055
|
const rect = this.convertPageRectToDeviceRect(page, pagePtr, pageRect);
|
|
2908
3056
|
const author = this.getAnnotString(annotationPtr, 'T');
|
|
2909
3057
|
const modifiedRaw = this.getAnnotString(annotationPtr, 'M');
|
|
2910
|
-
const modified =
|
|
2911
|
-
const
|
|
3058
|
+
const modified = models.pdfDateToDate(modifiedRaw);
|
|
3059
|
+
const segmentRects = this.getQuadPointsAnno(page, annotationPtr);
|
|
3060
|
+
const contents = this.getAnnotString(annotationPtr, 'Contents') || '';
|
|
3061
|
+
const webAlphaColor = this.resolveAnnotationColor(annotationPtr);
|
|
2912
3062
|
return {
|
|
2913
|
-
status: models.PdfAnnotationObjectStatus.Committed,
|
|
2914
3063
|
pageIndex: page.index,
|
|
2915
3064
|
id: index,
|
|
2916
3065
|
type: models.PdfAnnotationSubtype.STRIKEOUT,
|
|
2917
3066
|
rect,
|
|
2918
|
-
|
|
2919
|
-
|
|
3067
|
+
contents,
|
|
3068
|
+
segmentRects,
|
|
3069
|
+
...webAlphaColor,
|
|
2920
3070
|
author,
|
|
2921
3071
|
modified,
|
|
2922
3072
|
};
|
|
@@ -2932,21 +3082,22 @@ class PdfiumEngine {
|
|
|
2932
3082
|
* @private
|
|
2933
3083
|
*/
|
|
2934
3084
|
readPdfSquigglyAnno(page, pagePtr, annotationPtr, index) {
|
|
2935
|
-
const appearances = this.readPageAnnoAppearanceStreams(annotationPtr);
|
|
2936
3085
|
const pageRect = this.readPageAnnoRect(annotationPtr);
|
|
2937
3086
|
const rect = this.convertPageRectToDeviceRect(page, pagePtr, pageRect);
|
|
2938
3087
|
const author = this.getAnnotString(annotationPtr, 'T');
|
|
2939
3088
|
const modifiedRaw = this.getAnnotString(annotationPtr, 'M');
|
|
2940
|
-
const modified =
|
|
2941
|
-
const
|
|
3089
|
+
const modified = models.pdfDateToDate(modifiedRaw);
|
|
3090
|
+
const segmentRects = this.getQuadPointsAnno(page, annotationPtr);
|
|
3091
|
+
const contents = this.getAnnotString(annotationPtr, 'Contents') || '';
|
|
3092
|
+
const webAlphaColor = this.resolveAnnotationColor(annotationPtr);
|
|
2942
3093
|
return {
|
|
2943
|
-
status: models.PdfAnnotationObjectStatus.Committed,
|
|
2944
3094
|
pageIndex: page.index,
|
|
2945
3095
|
id: index,
|
|
2946
3096
|
type: models.PdfAnnotationSubtype.SQUIGGLY,
|
|
2947
3097
|
rect,
|
|
2948
|
-
|
|
2949
|
-
|
|
3098
|
+
contents,
|
|
3099
|
+
segmentRects,
|
|
3100
|
+
...webAlphaColor,
|
|
2950
3101
|
author,
|
|
2951
3102
|
modified,
|
|
2952
3103
|
};
|
|
@@ -2962,21 +3113,16 @@ class PdfiumEngine {
|
|
|
2962
3113
|
* @private
|
|
2963
3114
|
*/
|
|
2964
3115
|
readPdfCaretAnno(page, pagePtr, annotationPtr, index) {
|
|
2965
|
-
const appearances = this.readPageAnnoAppearanceStreams(annotationPtr);
|
|
2966
3116
|
const pageRect = this.readPageAnnoRect(annotationPtr);
|
|
2967
3117
|
const rect = this.convertPageRectToDeviceRect(page, pagePtr, pageRect);
|
|
2968
3118
|
const author = this.getAnnotString(annotationPtr, 'T');
|
|
2969
3119
|
const modifiedRaw = this.getAnnotString(annotationPtr, 'M');
|
|
2970
|
-
const modified =
|
|
2971
|
-
const popup = this.readPdfAnnoLinkedPopup(page, pagePtr, annotationPtr, index);
|
|
3120
|
+
const modified = models.pdfDateToDate(modifiedRaw);
|
|
2972
3121
|
return {
|
|
2973
|
-
status: models.PdfAnnotationObjectStatus.Committed,
|
|
2974
3122
|
pageIndex: page.index,
|
|
2975
3123
|
id: index,
|
|
2976
3124
|
type: models.PdfAnnotationSubtype.CARET,
|
|
2977
3125
|
rect,
|
|
2978
|
-
popup,
|
|
2979
|
-
appearances,
|
|
2980
3126
|
author,
|
|
2981
3127
|
modified,
|
|
2982
3128
|
};
|
|
@@ -2993,13 +3139,11 @@ class PdfiumEngine {
|
|
|
2993
3139
|
* @private
|
|
2994
3140
|
*/
|
|
2995
3141
|
readPdfStampAnno(docPtr, page, pagePtr, annotationPtr, index) {
|
|
2996
|
-
const appearances = this.readPageAnnoAppearanceStreams(annotationPtr);
|
|
2997
3142
|
const pageRect = this.readPageAnnoRect(annotationPtr);
|
|
2998
3143
|
const rect = this.convertPageRectToDeviceRect(page, pagePtr, pageRect);
|
|
2999
3144
|
const author = this.getAnnotString(annotationPtr, 'T');
|
|
3000
3145
|
const modifiedRaw = this.getAnnotString(annotationPtr, 'M');
|
|
3001
|
-
const modified =
|
|
3002
|
-
const popup = this.readPdfAnnoLinkedPopup(page, pagePtr, annotationPtr, index);
|
|
3146
|
+
const modified = models.pdfDateToDate(modifiedRaw);
|
|
3003
3147
|
const contents = [];
|
|
3004
3148
|
const objectCount = this.pdfiumModule.FPDFAnnot_GetObjectCount(annotationPtr);
|
|
3005
3149
|
for (let i = 0; i < objectCount; i++) {
|
|
@@ -3010,14 +3154,11 @@ class PdfiumEngine {
|
|
|
3010
3154
|
}
|
|
3011
3155
|
}
|
|
3012
3156
|
return {
|
|
3013
|
-
status: models.PdfAnnotationObjectStatus.Committed,
|
|
3014
3157
|
pageIndex: page.index,
|
|
3015
3158
|
id: index,
|
|
3016
3159
|
type: models.PdfAnnotationSubtype.STAMP,
|
|
3017
3160
|
rect,
|
|
3018
|
-
popup,
|
|
3019
3161
|
contents,
|
|
3020
|
-
appearances,
|
|
3021
3162
|
author,
|
|
3022
3163
|
modified,
|
|
3023
3164
|
};
|
|
@@ -3197,21 +3338,16 @@ class PdfiumEngine {
|
|
|
3197
3338
|
* @private
|
|
3198
3339
|
*/
|
|
3199
3340
|
readPdfCircleAnno(page, pagePtr, annotationPtr, index) {
|
|
3200
|
-
const appearances = this.readPageAnnoAppearanceStreams(annotationPtr);
|
|
3201
3341
|
const pageRect = this.readPageAnnoRect(annotationPtr);
|
|
3202
3342
|
const rect = this.convertPageRectToDeviceRect(page, pagePtr, pageRect);
|
|
3203
3343
|
const author = this.getAnnotString(annotationPtr, 'T');
|
|
3204
3344
|
const modifiedRaw = this.getAnnotString(annotationPtr, 'M');
|
|
3205
|
-
const modified =
|
|
3206
|
-
const popup = this.readPdfAnnoLinkedPopup(page, pagePtr, annotationPtr, index);
|
|
3345
|
+
const modified = models.pdfDateToDate(modifiedRaw);
|
|
3207
3346
|
return {
|
|
3208
|
-
status: models.PdfAnnotationObjectStatus.Committed,
|
|
3209
3347
|
pageIndex: page.index,
|
|
3210
3348
|
id: index,
|
|
3211
3349
|
type: models.PdfAnnotationSubtype.CIRCLE,
|
|
3212
3350
|
rect,
|
|
3213
|
-
popup,
|
|
3214
|
-
appearances,
|
|
3215
3351
|
author,
|
|
3216
3352
|
modified,
|
|
3217
3353
|
};
|
|
@@ -3227,21 +3363,16 @@ class PdfiumEngine {
|
|
|
3227
3363
|
* @private
|
|
3228
3364
|
*/
|
|
3229
3365
|
readPdfSquareAnno(page, pagePtr, annotationPtr, index) {
|
|
3230
|
-
const appearances = this.readPageAnnoAppearanceStreams(annotationPtr);
|
|
3231
3366
|
const pageRect = this.readPageAnnoRect(annotationPtr);
|
|
3232
3367
|
const rect = this.convertPageRectToDeviceRect(page, pagePtr, pageRect);
|
|
3233
3368
|
const author = this.getAnnotString(annotationPtr, 'T');
|
|
3234
3369
|
const modifiedRaw = this.getAnnotString(annotationPtr, 'M');
|
|
3235
|
-
const modified =
|
|
3236
|
-
const popup = this.readPdfAnnoLinkedPopup(page, pagePtr, annotationPtr, index);
|
|
3370
|
+
const modified = models.pdfDateToDate(modifiedRaw);
|
|
3237
3371
|
return {
|
|
3238
|
-
status: models.PdfAnnotationObjectStatus.Committed,
|
|
3239
3372
|
pageIndex: page.index,
|
|
3240
3373
|
id: index,
|
|
3241
3374
|
type: models.PdfAnnotationSubtype.SQUARE,
|
|
3242
3375
|
rect,
|
|
3243
|
-
popup,
|
|
3244
|
-
appearances,
|
|
3245
3376
|
author,
|
|
3246
3377
|
modified,
|
|
3247
3378
|
};
|
|
@@ -3258,21 +3389,16 @@ class PdfiumEngine {
|
|
|
3258
3389
|
* @private
|
|
3259
3390
|
*/
|
|
3260
3391
|
readPdfAnno(page, pagePtr, type, annotationPtr, index) {
|
|
3261
|
-
const appearances = this.readPageAnnoAppearanceStreams(annotationPtr);
|
|
3262
3392
|
const pageRect = this.readPageAnnoRect(annotationPtr);
|
|
3263
3393
|
const rect = this.convertPageRectToDeviceRect(page, pagePtr, pageRect);
|
|
3264
3394
|
const author = this.getAnnotString(annotationPtr, 'T');
|
|
3265
3395
|
const modifiedRaw = this.getAnnotString(annotationPtr, 'M');
|
|
3266
|
-
const modified =
|
|
3267
|
-
const popup = this.readPdfAnnoLinkedPopup(page, pagePtr, annotationPtr, index);
|
|
3396
|
+
const modified = models.pdfDateToDate(modifiedRaw);
|
|
3268
3397
|
return {
|
|
3269
|
-
status: models.PdfAnnotationObjectStatus.Committed,
|
|
3270
3398
|
pageIndex: page.index,
|
|
3271
3399
|
id: index,
|
|
3272
3400
|
type,
|
|
3273
3401
|
rect,
|
|
3274
|
-
popup,
|
|
3275
|
-
appearances,
|
|
3276
3402
|
author,
|
|
3277
3403
|
modified,
|
|
3278
3404
|
};
|
|
@@ -3294,25 +3420,6 @@ class PdfiumEngine {
|
|
|
3294
3420
|
const idx = this.pdfiumModule.FPDFPage_GetAnnotIndex(pagePtr, parentPtr);
|
|
3295
3421
|
return idx >= 0 ? idx : undefined;
|
|
3296
3422
|
}
|
|
3297
|
-
/**
|
|
3298
|
-
* Parse a PDF date string **D:YYYYMMDDHHmmSSOHH'mm'** to ISO-8601.
|
|
3299
|
-
*
|
|
3300
|
-
* Returns `undefined` if the input is malformed.
|
|
3301
|
-
*
|
|
3302
|
-
* @private
|
|
3303
|
-
*/
|
|
3304
|
-
toIsoDate(pdfDate) {
|
|
3305
|
-
if (!pdfDate?.startsWith('D:'))
|
|
3306
|
-
return;
|
|
3307
|
-
// Minimal parse – ignore timezone for brevity
|
|
3308
|
-
const y = pdfDate.substring(2, 6);
|
|
3309
|
-
const m = pdfDate.substring(6, 8) || '01';
|
|
3310
|
-
const d = pdfDate.substring(8, 10) || '01';
|
|
3311
|
-
const H = pdfDate.substring(10, 12) || '00';
|
|
3312
|
-
const M = pdfDate.substring(12, 14) || '00';
|
|
3313
|
-
const S = pdfDate.substring(14, 16) || '00';
|
|
3314
|
-
return `${y}-${m}-${d}T${H}:${M}:${S}`;
|
|
3315
|
-
}
|
|
3316
3423
|
/**
|
|
3317
3424
|
* Fetch a string value (`/T`, `/M`, `/State`, …) from an annotation.
|
|
3318
3425
|
*
|
|
@@ -3332,41 +3439,19 @@ class PdfiumEngine {
|
|
|
3332
3439
|
return value || undefined;
|
|
3333
3440
|
}
|
|
3334
3441
|
/**
|
|
3335
|
-
*
|
|
3336
|
-
*
|
|
3337
|
-
* @
|
|
3338
|
-
* @param annotationPtr - pointer to pdf annotation
|
|
3339
|
-
* @param index - index of annotation in the pdf page
|
|
3340
|
-
* @returns pdf popup linked to annotation
|
|
3442
|
+
* Set a string value (`/T`, `/M`, `/State`, …) to an annotation.
|
|
3443
|
+
*
|
|
3444
|
+
* @returns `true` if the operation was successful
|
|
3341
3445
|
*
|
|
3342
3446
|
* @private
|
|
3343
3447
|
*/
|
|
3344
|
-
|
|
3345
|
-
const
|
|
3346
|
-
const
|
|
3347
|
-
|
|
3348
|
-
|
|
3349
|
-
|
|
3350
|
-
|
|
3351
|
-
const rect = this.convertPageRectToDeviceRect(page, pagePtr, pageRect);
|
|
3352
|
-
const author = this.getAnnotString(annotationPtr, 'T');
|
|
3353
|
-
const modifiedRaw = this.getAnnotString(annotationPtr, 'M');
|
|
3354
|
-
const modified = this.toIsoDate(modifiedRaw);
|
|
3355
|
-
const contents = this.getAnnotString(annotationPtr, 'Contents') || '';
|
|
3356
|
-
const open = this.getAnnotString(annotationPtr, 'Open') || 'false';
|
|
3357
|
-
this.pdfiumModule.FPDFPage_CloseAnnot(popupAnnotationPtr);
|
|
3358
|
-
return {
|
|
3359
|
-
status: models.PdfAnnotationObjectStatus.Committed,
|
|
3360
|
-
pageIndex: page.index,
|
|
3361
|
-
id: index,
|
|
3362
|
-
type: models.PdfAnnotationSubtype.POPUP,
|
|
3363
|
-
rect,
|
|
3364
|
-
contents,
|
|
3365
|
-
open: open === 'true',
|
|
3366
|
-
appearances,
|
|
3367
|
-
author,
|
|
3368
|
-
modified,
|
|
3369
|
-
};
|
|
3448
|
+
setAnnotString(annotationPtr, key, value) {
|
|
3449
|
+
const bytes = 2 * (value.length + 1);
|
|
3450
|
+
const ptr = this.malloc(bytes);
|
|
3451
|
+
this.pdfiumModule.pdfium.stringToUTF16(value, ptr, bytes);
|
|
3452
|
+
const ok = this.pdfiumModule.FPDFAnnot_SetStringValue(annotationPtr, key, ptr);
|
|
3453
|
+
this.free(ptr);
|
|
3454
|
+
return ok;
|
|
3370
3455
|
}
|
|
3371
3456
|
/**
|
|
3372
3457
|
* Read vertices of pdf annotation
|
|
@@ -3807,6 +3892,69 @@ class PdfiumEngine {
|
|
|
3807
3892
|
this.free(bufferPtr);
|
|
3808
3893
|
return ap;
|
|
3809
3894
|
}
|
|
3895
|
+
/**
|
|
3896
|
+
* Change the visible colour (and opacity) of an existing annotation.
|
|
3897
|
+
*
|
|
3898
|
+
* For markup annotations (highlight / underline / strikeout / squiggly) we
|
|
3899
|
+
* first clear the AP dictionary entry, otherwise the stored appearance stream
|
|
3900
|
+
* will override the new tint. For all other sub-types we keep the existing
|
|
3901
|
+
* AP so custom artwork isn't lost.
|
|
3902
|
+
*
|
|
3903
|
+
* @param doc logical document object
|
|
3904
|
+
* @param page logical page object
|
|
3905
|
+
* @param annotation the annotation we want to recolour
|
|
3906
|
+
* @param colour RGBA tuple (0-255 per channel)
|
|
3907
|
+
* @param which 0 = stroke/fill colour (PDFium's "colourType" param)
|
|
3908
|
+
*
|
|
3909
|
+
* @returns `true` when the operation succeeded
|
|
3910
|
+
*/
|
|
3911
|
+
updateAnnotationColor(doc, page, annotation, color, which = 0) {
|
|
3912
|
+
this.logger.debug(LOG_SOURCE$1, LOG_CATEGORY$1, 'setAnnotationColor', doc, page, annotation, color, which);
|
|
3913
|
+
this.logger.perf(LOG_SOURCE$1, LOG_CATEGORY$1, 'setAnnotationColor', 'Begin', doc.id);
|
|
3914
|
+
const task = models.PdfTaskHelper.create();
|
|
3915
|
+
try {
|
|
3916
|
+
/* 1 ── sanity & native handles ────────────────────────────────────────── */
|
|
3917
|
+
const ctx = this.cache.getContext(doc.id);
|
|
3918
|
+
if (!ctx) {
|
|
3919
|
+
this.logger.perf(LOG_SOURCE$1, LOG_CATEGORY$1, 'setAnnotationColor', 'End', doc.id);
|
|
3920
|
+
this.logger.warn(LOG_SOURCE$1, LOG_CATEGORY$1, 'setAnnotationColor: doc closed');
|
|
3921
|
+
task.resolve(false);
|
|
3922
|
+
return task;
|
|
3923
|
+
}
|
|
3924
|
+
const pageCtx = ctx.acquirePage(page.index);
|
|
3925
|
+
const annotPtr = this.pdfiumModule.FPDFPage_GetAnnot(pageCtx.pagePtr, annotation.id);
|
|
3926
|
+
if (!annotPtr) {
|
|
3927
|
+
this.logger.perf(LOG_SOURCE$1, LOG_CATEGORY$1, 'setAnnotationColor', 'End', doc.id);
|
|
3928
|
+
this.logger.warn(LOG_SOURCE$1, LOG_CATEGORY$1, 'setAnnotationColor: annot not found');
|
|
3929
|
+
pageCtx.release();
|
|
3930
|
+
task.resolve(false);
|
|
3931
|
+
return task;
|
|
3932
|
+
}
|
|
3933
|
+
/* 2 ── wipe AP if it's a simple markup annotation ─────────────────────── */
|
|
3934
|
+
const shouldClearAP = annotation.type === models.PdfAnnotationSubtype.HIGHLIGHT ||
|
|
3935
|
+
annotation.type === models.PdfAnnotationSubtype.UNDERLINE ||
|
|
3936
|
+
annotation.type === models.PdfAnnotationSubtype.STRIKEOUT ||
|
|
3937
|
+
annotation.type === models.PdfAnnotationSubtype.SQUIGGLY;
|
|
3938
|
+
const ok = this.setAnnotationColor(annotPtr, color, shouldClearAP, which);
|
|
3939
|
+
/* 4 ── regenerate appearance & clean-up ───────────────────────────────── */
|
|
3940
|
+
if (ok) {
|
|
3941
|
+
this.pdfiumModule.FPDFPage_GenerateContent(pageCtx.pagePtr);
|
|
3942
|
+
}
|
|
3943
|
+
this.pdfiumModule.FPDFPage_CloseAnnot(annotPtr);
|
|
3944
|
+
pageCtx.release();
|
|
3945
|
+
this.logger.perf(LOG_SOURCE$1, LOG_CATEGORY$1, 'setAnnotationColor', 'End', doc.id);
|
|
3946
|
+
task.resolve(!!ok);
|
|
3947
|
+
}
|
|
3948
|
+
catch (error) {
|
|
3949
|
+
this.logger.perf(LOG_SOURCE$1, LOG_CATEGORY$1, 'setAnnotationColor', 'End', doc.id);
|
|
3950
|
+
this.logger.error(LOG_SOURCE$1, LOG_CATEGORY$1, 'setAnnotationColor: error', error);
|
|
3951
|
+
task.reject({
|
|
3952
|
+
code: models.PdfErrorCode.Unknown,
|
|
3953
|
+
message: `Failed to set annotation color: ${error instanceof Error ? error.message : String(error)}`,
|
|
3954
|
+
});
|
|
3955
|
+
}
|
|
3956
|
+
return task;
|
|
3957
|
+
}
|
|
3810
3958
|
/**
|
|
3811
3959
|
* Set the rect of specified annotation
|
|
3812
3960
|
* @param page - page info that the annotation is belonged to
|
|
@@ -4142,7 +4290,7 @@ class EngineRunner {
|
|
|
4142
4290
|
type: 'reject',
|
|
4143
4291
|
reason: {
|
|
4144
4292
|
code: models.PdfErrorCode.NotSupport,
|
|
4145
|
-
message:
|
|
4293
|
+
message: `engine method ${name} is not supported yet`,
|
|
4146
4294
|
},
|
|
4147
4295
|
};
|
|
4148
4296
|
const response = {
|
|
@@ -4209,12 +4357,18 @@ class EngineRunner {
|
|
|
4209
4357
|
case 'createPageAnnotation':
|
|
4210
4358
|
task = this.engine[name](...args);
|
|
4211
4359
|
break;
|
|
4360
|
+
case 'updatePageAnnotation':
|
|
4361
|
+
task = this.engine[name](...args);
|
|
4362
|
+
break;
|
|
4212
4363
|
case 'transformPageAnnotation':
|
|
4213
4364
|
task = this.engine[name](...args);
|
|
4214
4365
|
break;
|
|
4215
4366
|
case 'removePageAnnotation':
|
|
4216
4367
|
task = this.engine[name](...args);
|
|
4217
4368
|
break;
|
|
4369
|
+
case 'updateAnnotationColor':
|
|
4370
|
+
task = this.engine[name](...args);
|
|
4371
|
+
break;
|
|
4218
4372
|
case 'getPageTextRects':
|
|
4219
4373
|
task = this.engine[name](...args);
|
|
4220
4374
|
break;
|