@embedpdf/engines 1.0.6 → 1.0.8
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 +709 -378
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +162 -66
- package/dist/index.js +710 -379
- package/dist/index.js.map +1 -1
- package/dist/pdfium-direct-engine.cjs +653 -358
- package/dist/pdfium-direct-engine.cjs.map +1 -1
- package/dist/pdfium-direct-engine.d.ts +153 -59
- package/dist/pdfium-direct-engine.js +654 -359
- package/dist/pdfium-direct-engine.js.map +1 -1
- package/dist/pdfium-worker-engine.cjs +40 -10
- package/dist/pdfium-worker-engine.cjs.map +1 -1
- package/dist/pdfium-worker-engine.d.ts +10 -8
- package/dist/pdfium-worker-engine.js +40 -10
- package/dist/pdfium-worker-engine.js.map +1 -1
- package/dist/pdfium.cjs +661 -360
- package/dist/pdfium.cjs.map +1 -1
- package/dist/pdfium.d.ts +153 -59
- package/dist/pdfium.js +662 -361
- package/dist/pdfium.js.map +1 -1
- package/dist/preact.cjs +4 -3
- package/dist/preact.cjs.map +1 -1
- package/dist/preact.d.ts +4 -3
- package/dist/preact.js +4 -3
- package/dist/preact.js.map +1 -1
- package/dist/react.cjs +4 -3
- package/dist/react.cjs.map +1 -1
- package/dist/react.d.ts +4 -3
- package/dist/react.js +4 -3
- package/dist/react.js.map +1 -1
- package/dist/worker.cjs +39 -9
- package/dist/worker.cjs.map +1 -1
- package/dist/worker.d.ts +10 -8
- package/dist/worker.js +39 -9
- package/dist/worker.js.map +1 -1
- package/package.json +3 -3
package/dist/pdfium.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { NoopLogger, PdfTaskHelper, PdfErrorCode, Task, Rotation, PdfAnnotationSubtype, stripPdfUnwantedMarkers, PdfPageObjectType,
|
|
1
|
+
import { NoopLogger, PdfTaskHelper, PdfErrorCode, Task, Rotation, PdfAnnotationSubtype, stripPdfUnwantedMarkers, PdfAnnotationBorderStyle, dateToPdfDate, PdfAnnotationColorType, PdfPageObjectType, pdfAlphaColorToWebAlphaColor, webAlphaColorToPdfAlphaColor, quadToRect, pdfDateToDate, flagsToNames, PDF_FORM_FIELD_TYPE, toIntRect, transformRect, makeMatrix, AppearanceMode, toIntSize, transformSize, PdfActionType, PdfZoomMode, MatchFlag, rectToQuad } from '@embedpdf/models';
|
|
2
2
|
import { init } from '@embedpdf/pdfium';
|
|
3
3
|
|
|
4
4
|
/**
|
|
@@ -910,11 +910,17 @@ class PdfiumEngine {
|
|
|
910
910
|
let isSucceed = false;
|
|
911
911
|
switch (annotation.type) {
|
|
912
912
|
case PdfAnnotationSubtype.INK:
|
|
913
|
-
isSucceed = this.addInkStroke(page, pageCtx.pagePtr, annotationPtr, annotation
|
|
913
|
+
isSucceed = this.addInkStroke(page, pageCtx.pagePtr, annotationPtr, annotation);
|
|
914
914
|
break;
|
|
915
915
|
case PdfAnnotationSubtype.STAMP:
|
|
916
916
|
isSucceed = this.addStampContent(ctx.docPtr, page, pageCtx.pagePtr, annotationPtr, annotation.rect, annotation.contents);
|
|
917
917
|
break;
|
|
918
|
+
case PdfAnnotationSubtype.UNDERLINE:
|
|
919
|
+
case PdfAnnotationSubtype.STRIKEOUT:
|
|
920
|
+
case PdfAnnotationSubtype.SQUIGGLY:
|
|
921
|
+
case PdfAnnotationSubtype.HIGHLIGHT:
|
|
922
|
+
isSucceed = this.addTextMarkupContent(page, pageCtx.pagePtr, annotationPtr, annotation);
|
|
923
|
+
break;
|
|
918
924
|
}
|
|
919
925
|
if (!isSucceed) {
|
|
920
926
|
this.pdfiumModule.FPDFPage_RemoveAnnot(pageCtx.pagePtr, annotationPtr);
|
|
@@ -925,90 +931,104 @@ class PdfiumEngine {
|
|
|
925
931
|
message: 'can not add content of the annotation',
|
|
926
932
|
});
|
|
927
933
|
}
|
|
934
|
+
this.pdfiumModule.EPDFAnnot_GenerateAppearance(annotationPtr);
|
|
928
935
|
this.pdfiumModule.FPDFPage_GenerateContent(pageCtx.pagePtr);
|
|
936
|
+
const annotId = this.pdfiumModule.FPDFPage_GetAnnotIndex(pageCtx.pagePtr, annotationPtr);
|
|
929
937
|
this.pdfiumModule.FPDFPage_CloseAnnot(annotationPtr);
|
|
930
938
|
pageCtx.release();
|
|
931
939
|
this.logger.perf(LOG_SOURCE$1, LOG_CATEGORY$1, `CreatePageAnnotation`, 'End', `${doc.id}-${page.index}`);
|
|
932
|
-
return
|
|
940
|
+
return annotId >= 0
|
|
941
|
+
? PdfTaskHelper.resolve(annotId)
|
|
942
|
+
: PdfTaskHelper.reject({
|
|
943
|
+
code: PdfErrorCode.CantCreateAnnot,
|
|
944
|
+
message: 'annotation created but index could not be determined',
|
|
945
|
+
});
|
|
933
946
|
}
|
|
934
947
|
/**
|
|
935
|
-
*
|
|
948
|
+
* Update an existing page annotation in-place
|
|
936
949
|
*
|
|
937
|
-
*
|
|
950
|
+
* • Locates the annot by page-local index (`annotation.id`)
|
|
951
|
+
* • Re-writes its /Rect and type-specific payload
|
|
952
|
+
* • Calls FPDFPage_GenerateContent so the new appearance is rendered
|
|
953
|
+
*
|
|
954
|
+
* @returns PdfTask<boolean> – true on success
|
|
938
955
|
*/
|
|
939
|
-
|
|
940
|
-
this.logger.debug(LOG_SOURCE$1, LOG_CATEGORY$1, '
|
|
941
|
-
this.logger.perf(LOG_SOURCE$1, LOG_CATEGORY$1,
|
|
956
|
+
updatePageAnnotation(doc, page, annotation) {
|
|
957
|
+
this.logger.debug(LOG_SOURCE$1, LOG_CATEGORY$1, 'updatePageAnnotation', doc, page, annotation);
|
|
958
|
+
this.logger.perf(LOG_SOURCE$1, LOG_CATEGORY$1, 'UpdatePageAnnotation', 'Begin', `${doc.id}-${page.index}`);
|
|
942
959
|
const ctx = this.cache.getContext(doc.id);
|
|
943
960
|
if (!ctx) {
|
|
944
|
-
this.logger.perf(LOG_SOURCE$1, LOG_CATEGORY$1,
|
|
961
|
+
this.logger.perf(LOG_SOURCE$1, LOG_CATEGORY$1, 'UpdatePageAnnotation', 'End', `${doc.id}-${page.index}`);
|
|
945
962
|
return PdfTaskHelper.reject({
|
|
946
963
|
code: PdfErrorCode.DocNotOpen,
|
|
947
964
|
message: 'document does not open',
|
|
948
965
|
});
|
|
949
966
|
}
|
|
950
967
|
const pageCtx = ctx.acquirePage(page.index);
|
|
951
|
-
const
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
},
|
|
961
|
-
};
|
|
962
|
-
if (!this.setPageAnnoRect(page, pageCtx.pagePtr, annotationPtr, rect)) {
|
|
963
|
-
this.pdfiumModule.FPDFPage_CloseAnnot(annotationPtr);
|
|
968
|
+
const annotPtr = this.pdfiumModule.FPDFPage_GetAnnot(pageCtx.pagePtr, annotation.id);
|
|
969
|
+
if (!annotPtr) {
|
|
970
|
+
pageCtx.release();
|
|
971
|
+
this.logger.perf(LOG_SOURCE$1, LOG_CATEGORY$1, 'UpdatePageAnnotation', 'End', `${doc.id}-${page.index}`);
|
|
972
|
+
return PdfTaskHelper.reject({ code: PdfErrorCode.NotFound, message: 'annotation not found' });
|
|
973
|
+
}
|
|
974
|
+
/* 1 ── (re)set bounding-box ────────────────────────────────────────────── */
|
|
975
|
+
if (!this.setPageAnnoRect(page, pageCtx.pagePtr, annotPtr, annotation.rect)) {
|
|
976
|
+
this.pdfiumModule.FPDFPage_CloseAnnot(annotPtr);
|
|
964
977
|
pageCtx.release();
|
|
965
|
-
this.logger.perf(LOG_SOURCE$1, LOG_CATEGORY$1,
|
|
978
|
+
this.logger.perf(LOG_SOURCE$1, LOG_CATEGORY$1, 'UpdatePageAnnotation', 'End', `${doc.id}-${page.index}`);
|
|
966
979
|
return PdfTaskHelper.reject({
|
|
967
980
|
code: PdfErrorCode.CantSetAnnotRect,
|
|
968
|
-
message: '
|
|
981
|
+
message: 'failed to move annotation',
|
|
969
982
|
});
|
|
970
983
|
}
|
|
984
|
+
/* 2 ── wipe previous payload and rebuild fresh one ─────────────────────── */
|
|
985
|
+
let ok = false;
|
|
971
986
|
switch (annotation.type) {
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
points: inkStroke.points.map((point) => {
|
|
986
|
-
return {
|
|
987
|
-
x: rect.origin.x +
|
|
988
|
-
(point.x - annotation.rect.origin.x) * transformation.scale.width,
|
|
989
|
-
y: rect.origin.y +
|
|
990
|
-
(point.y - annotation.rect.origin.y) * transformation.scale.height,
|
|
991
|
-
};
|
|
992
|
-
}),
|
|
993
|
-
};
|
|
994
|
-
});
|
|
995
|
-
if (!this.addInkStroke(page, pageCtx.pagePtr, annotationPtr, inkList)) {
|
|
996
|
-
this.pdfiumModule.FPDFPage_CloseAnnot(annotationPtr);
|
|
997
|
-
pageCtx.release();
|
|
998
|
-
this.logger.perf(LOG_SOURCE$1, LOG_CATEGORY$1, `TransformPageAnnotation`, 'End', `${doc.id}-${page.index}`);
|
|
999
|
-
return PdfTaskHelper.reject({
|
|
1000
|
-
code: PdfErrorCode.CantAddInkStoke,
|
|
1001
|
-
message: 'can not add stroke to the ink list of annotation',
|
|
1002
|
-
});
|
|
1003
|
-
}
|
|
987
|
+
/* ── Ink ─────────────────────────────────────────────────────────────── */
|
|
988
|
+
case PdfAnnotationSubtype.INK: {
|
|
989
|
+
/* clear every existing stroke first */
|
|
990
|
+
if (!this.pdfiumModule.FPDFAnnot_RemoveInkList(annotPtr))
|
|
991
|
+
break;
|
|
992
|
+
ok = this.addInkStroke(page, pageCtx.pagePtr, annotPtr, annotation);
|
|
993
|
+
break;
|
|
994
|
+
}
|
|
995
|
+
/* ── Stamp ───────────────────────────────────────────────────────────── */
|
|
996
|
+
case PdfAnnotationSubtype.STAMP: {
|
|
997
|
+
/* drop every page-object inside the annot */
|
|
998
|
+
for (let i = this.pdfiumModule.FPDFAnnot_GetObjectCount(annotPtr) - 1; i >= 0; i--) {
|
|
999
|
+
this.pdfiumModule.FPDFAnnot_RemoveObject(annotPtr, i);
|
|
1004
1000
|
}
|
|
1001
|
+
ok = this.addStampContent(ctx.docPtr, page, pageCtx.pagePtr, annotPtr, annotation.rect, annotation.contents);
|
|
1002
|
+
break;
|
|
1003
|
+
}
|
|
1004
|
+
/* ── Text-markup family ──────────────────────────────────────────────── */
|
|
1005
|
+
case PdfAnnotationSubtype.HIGHLIGHT:
|
|
1006
|
+
case PdfAnnotationSubtype.UNDERLINE:
|
|
1007
|
+
case PdfAnnotationSubtype.STRIKEOUT:
|
|
1008
|
+
case PdfAnnotationSubtype.SQUIGGLY: {
|
|
1009
|
+
/* replace quad-points / colour / strings in one go */
|
|
1010
|
+
ok = this.addTextMarkupContent(page, pageCtx.pagePtr, annotPtr, annotation);
|
|
1005
1011
|
break;
|
|
1012
|
+
}
|
|
1013
|
+
/* ── Unsupported edits – fall through to error ───────────────────────── */
|
|
1014
|
+
default:
|
|
1015
|
+
ok = false;
|
|
1006
1016
|
}
|
|
1007
|
-
|
|
1008
|
-
|
|
1017
|
+
/* 3 ── regenerate appearance if payload was changed ───────────────────── */
|
|
1018
|
+
if (ok) {
|
|
1019
|
+
this.pdfiumModule.EPDFAnnot_GenerateAppearance(annotPtr);
|
|
1020
|
+
this.pdfiumModule.FPDFPage_GenerateContent(pageCtx.pagePtr);
|
|
1021
|
+
}
|
|
1022
|
+
/* 4 ── tidy-up native handles ──────────────────────────────────────────── */
|
|
1023
|
+
this.pdfiumModule.FPDFPage_CloseAnnot(annotPtr);
|
|
1009
1024
|
pageCtx.release();
|
|
1010
|
-
this.logger.perf(LOG_SOURCE$1, LOG_CATEGORY$1,
|
|
1011
|
-
return
|
|
1025
|
+
this.logger.perf(LOG_SOURCE$1, LOG_CATEGORY$1, 'UpdatePageAnnotation', 'End', `${doc.id}-${page.index}`);
|
|
1026
|
+
return ok
|
|
1027
|
+
? PdfTaskHelper.resolve(true)
|
|
1028
|
+
: PdfTaskHelper.reject({
|
|
1029
|
+
code: PdfErrorCode.CantSetAnnotContent,
|
|
1030
|
+
message: 'failed to update annotation',
|
|
1031
|
+
});
|
|
1012
1032
|
}
|
|
1013
1033
|
/**
|
|
1014
1034
|
* {@inheritDoc @embedpdf/models!PdfEngine.removePageAnnotation}
|
|
@@ -1630,21 +1650,60 @@ class PdfiumEngine {
|
|
|
1630
1650
|
*
|
|
1631
1651
|
* @private
|
|
1632
1652
|
*/
|
|
1633
|
-
addInkStroke(page, pagePtr, annotationPtr,
|
|
1634
|
-
|
|
1635
|
-
|
|
1636
|
-
|
|
1637
|
-
|
|
1638
|
-
|
|
1639
|
-
|
|
1640
|
-
|
|
1641
|
-
|
|
1642
|
-
|
|
1643
|
-
|
|
1644
|
-
|
|
1645
|
-
|
|
1646
|
-
|
|
1647
|
-
|
|
1653
|
+
addInkStroke(page, pagePtr, annotationPtr, annotation) {
|
|
1654
|
+
if (!this.setBorderStyle(annotationPtr, PdfAnnotationBorderStyle.SOLID, annotation.strokeWidth)) {
|
|
1655
|
+
return false;
|
|
1656
|
+
}
|
|
1657
|
+
if (!this.setPageAnnoRect(page, pagePtr, annotationPtr, annotation.rect)) {
|
|
1658
|
+
return false;
|
|
1659
|
+
}
|
|
1660
|
+
if (!this.setInkList(page, annotationPtr, annotation.inkList)) {
|
|
1661
|
+
return false;
|
|
1662
|
+
}
|
|
1663
|
+
if (!this.setAnnotString(annotationPtr, 'T', annotation.author || '')) {
|
|
1664
|
+
return false;
|
|
1665
|
+
}
|
|
1666
|
+
if (!this.setAnnotString(annotationPtr, 'M', dateToPdfDate(annotation.modified))) {
|
|
1667
|
+
return false;
|
|
1668
|
+
}
|
|
1669
|
+
if (!this.setAnnotationColor(annotationPtr, {
|
|
1670
|
+
color: annotation.color ?? '#FFFF00',
|
|
1671
|
+
opacity: annotation.opacity ?? 1,
|
|
1672
|
+
}, PdfAnnotationColorType.Color)) {
|
|
1673
|
+
return false;
|
|
1674
|
+
}
|
|
1675
|
+
return true;
|
|
1676
|
+
}
|
|
1677
|
+
/**
|
|
1678
|
+
* Add highlight content to annotation
|
|
1679
|
+
* @param page - page info
|
|
1680
|
+
* @param annotationPtr - pointer to highlight annotation
|
|
1681
|
+
* @param annotation - highlight annotation
|
|
1682
|
+
* @returns whether highlight content is added to annotation
|
|
1683
|
+
*
|
|
1684
|
+
* @private
|
|
1685
|
+
*/
|
|
1686
|
+
addTextMarkupContent(page, pagePtr, annotationPtr, annotation) {
|
|
1687
|
+
if (!this.setPageAnnoRect(page, pagePtr, annotationPtr, annotation.rect)) {
|
|
1688
|
+
return false;
|
|
1689
|
+
}
|
|
1690
|
+
if (!this.syncQuadPointsAnno(page, annotationPtr, annotation.segmentRects)) {
|
|
1691
|
+
return false;
|
|
1692
|
+
}
|
|
1693
|
+
if (!this.setAnnotString(annotationPtr, 'Contents', annotation.contents ?? '')) {
|
|
1694
|
+
return false;
|
|
1695
|
+
}
|
|
1696
|
+
if (!this.setAnnotString(annotationPtr, 'T', annotation.author || '')) {
|
|
1697
|
+
return false;
|
|
1698
|
+
}
|
|
1699
|
+
if (!this.setAnnotString(annotationPtr, 'M', dateToPdfDate(annotation.modified))) {
|
|
1700
|
+
return false;
|
|
1701
|
+
}
|
|
1702
|
+
if (!this.setAnnotationColor(annotationPtr, {
|
|
1703
|
+
color: annotation.color ?? '#FFFF00',
|
|
1704
|
+
opacity: annotation.opacity ?? 1,
|
|
1705
|
+
}, PdfAnnotationColorType.Color)) {
|
|
1706
|
+
return false;
|
|
1648
1707
|
}
|
|
1649
1708
|
return true;
|
|
1650
1709
|
}
|
|
@@ -2270,8 +2329,6 @@ class PdfiumEngine {
|
|
|
2270
2329
|
annotation = this.readPdfCaretAnno(page, pageCtx.pagePtr, annotationPtr, index);
|
|
2271
2330
|
}
|
|
2272
2331
|
break;
|
|
2273
|
-
case PdfAnnotationSubtype.POPUP:
|
|
2274
|
-
break;
|
|
2275
2332
|
default:
|
|
2276
2333
|
{
|
|
2277
2334
|
annotation = this.readPdfAnno(page, pageCtx.pagePtr, subType, annotationPtr, index);
|
|
@@ -2292,14 +2349,13 @@ class PdfiumEngine {
|
|
|
2292
2349
|
*
|
|
2293
2350
|
* @private
|
|
2294
2351
|
*/
|
|
2295
|
-
readAnnotationColor(annotationPtr) {
|
|
2352
|
+
readAnnotationColor(annotationPtr, colorType = PdfAnnotationColorType.Color) {
|
|
2296
2353
|
const rPtr = this.malloc(4);
|
|
2297
2354
|
const gPtr = this.malloc(4);
|
|
2298
2355
|
const bPtr = this.malloc(4);
|
|
2299
2356
|
const aPtr = this.malloc(4);
|
|
2300
2357
|
// colourType 0 = "colour" (stroke/fill); other types are interior/border
|
|
2301
|
-
const ok = this.pdfiumModule.
|
|
2302
|
-
/* colorType = */ 0, rPtr, gPtr, bPtr, aPtr);
|
|
2358
|
+
const ok = this.pdfiumModule.EPDFAnnot_GetColor(annotationPtr, colorType, rPtr, gPtr, bPtr, aPtr);
|
|
2303
2359
|
let colour;
|
|
2304
2360
|
if (ok) {
|
|
2305
2361
|
colour = {
|
|
@@ -2317,116 +2373,144 @@ class PdfiumEngine {
|
|
|
2317
2373
|
}
|
|
2318
2374
|
/* --------------------------------------------------------------------------- */
|
|
2319
2375
|
/**
|
|
2320
|
-
*
|
|
2321
|
-
*
|
|
2376
|
+
* Resolve the visible fill colour for **Highlight / Underline / StrikeOut /
|
|
2377
|
+
* Squiggly** markup annotations.
|
|
2322
2378
|
*
|
|
2323
|
-
*
|
|
2324
|
-
*
|
|
2379
|
+
* Resolution order (first non-`undefined` wins):
|
|
2380
|
+
* 1. `/C` dictionary entry – fast, present in Acrobat / Office PDFs
|
|
2381
|
+
* 2. Appearance-stream objects – drills into paths & nested forms
|
|
2382
|
+
* 3. Hard-coded fallback (Acrobat-style opaque yellow)
|
|
2325
2383
|
*
|
|
2326
|
-
* @param
|
|
2327
|
-
* @
|
|
2384
|
+
* @param annotationPtr - pointer to an `FPDF_ANNOTATION`
|
|
2385
|
+
* @param fallback - colour to use when the PDF stores no tint at all
|
|
2386
|
+
* @returns WebAlphaColor with hex color and opacity (0-1)
|
|
2328
2387
|
*
|
|
2329
2388
|
* @private
|
|
2330
2389
|
*/
|
|
2331
|
-
|
|
2332
|
-
const
|
|
2333
|
-
|
|
2334
|
-
const strokeOk = !fillOk && // try stroke only if fill failed
|
|
2335
|
-
this.pdfiumModule.FPDFPageObj_GetStrokeColor(pathPtr, r, g, b, a);
|
|
2336
|
-
const ok = fillOk || strokeOk;
|
|
2337
|
-
let c;
|
|
2338
|
-
if (ok) {
|
|
2339
|
-
c = {
|
|
2340
|
-
red: this.pdfiumModule.pdfium.getValue(r, 'i32') & 0xff,
|
|
2341
|
-
green: this.pdfiumModule.pdfium.getValue(g, 'i32') & 0xff,
|
|
2342
|
-
blue: this.pdfiumModule.pdfium.getValue(b, 'i32') & 0xff,
|
|
2343
|
-
alpha: this.pdfiumModule.pdfium.getValue(a, 'i32') & 0xff,
|
|
2344
|
-
};
|
|
2345
|
-
}
|
|
2346
|
-
this.free(r);
|
|
2347
|
-
this.free(g);
|
|
2348
|
-
this.free(b);
|
|
2349
|
-
this.free(a);
|
|
2350
|
-
return c;
|
|
2390
|
+
resolveAnnotationColor(annotationPtr, colorType = PdfAnnotationColorType.Color, fallback = { red: 255, green: 245, blue: 155, alpha: 255 }) {
|
|
2391
|
+
const pdfColor = this.readAnnotationColor(annotationPtr, colorType) ?? fallback;
|
|
2392
|
+
return pdfAlphaColorToWebAlphaColor(pdfColor);
|
|
2351
2393
|
}
|
|
2352
|
-
/* --------------------------------------------------------------------------- */
|
|
2353
2394
|
/**
|
|
2354
|
-
*
|
|
2355
|
-
* a colour can be extracted.
|
|
2356
|
-
*
|
|
2357
|
-
* Acrobat often wraps its highlight rectangle in a Form XObject referenced by
|
|
2358
|
-
* the "Do" operator, so this function drills down unlimited depth.
|
|
2395
|
+
* Set the fill/stroke colour for a **Highlight / Underline / StrikeOut / Squiggly** markup annotation.
|
|
2359
2396
|
*
|
|
2360
|
-
* @param
|
|
2361
|
-
* @
|
|
2362
|
-
*
|
|
2397
|
+
* @param annotationPtr - pointer to the annotation whose colour is being set
|
|
2398
|
+
* @param webAlphaColor - WebAlphaColor with hex color and opacity (0-1)
|
|
2399
|
+
* @param shouldClearAP - whether to clear the /AP entry
|
|
2400
|
+
* @param which - which colour to set (0 = fill, 1 = stroke)
|
|
2401
|
+
* @returns `true` if the operation was successful
|
|
2363
2402
|
*
|
|
2364
2403
|
* @private
|
|
2365
2404
|
*/
|
|
2366
|
-
|
|
2367
|
-
const
|
|
2368
|
-
|
|
2369
|
-
return this.getColorFromPath(objPtr);
|
|
2370
|
-
if (type !== PdfPageObjectType.FORM)
|
|
2371
|
-
return undefined;
|
|
2372
|
-
const cnt = this.pdfiumModule.FPDFFormObj_CountObjects(objPtr);
|
|
2373
|
-
for (let i = 0; i < cnt; i++) {
|
|
2374
|
-
const child = this.pdfiumModule.FPDFFormObj_GetObject(objPtr, i);
|
|
2375
|
-
if (!child)
|
|
2376
|
-
continue;
|
|
2377
|
-
const c = this.walkPageObjTree(child);
|
|
2378
|
-
if (c)
|
|
2379
|
-
return c;
|
|
2380
|
-
}
|
|
2381
|
-
return undefined;
|
|
2405
|
+
setAnnotationColor(annotationPtr, webAlphaColor, colorType = PdfAnnotationColorType.Color) {
|
|
2406
|
+
const pdfAlphaColor = webAlphaColorToPdfAlphaColor(webAlphaColor);
|
|
2407
|
+
return this.pdfiumModule.EPDFAnnot_SetColor(annotationPtr, colorType, pdfAlphaColor.red & 0xff, pdfAlphaColor.green & 0xff, pdfAlphaColor.blue & 0xff, (pdfAlphaColor.alpha ?? 255) & 0xff);
|
|
2382
2408
|
}
|
|
2383
|
-
/* --------------------------------------------------------------------------- */
|
|
2384
2409
|
/**
|
|
2385
|
-
*
|
|
2386
|
-
* and invoke {@link walkPageObjTree} to locate a usable tint.
|
|
2410
|
+
* Border‐style + width helper
|
|
2387
2411
|
*
|
|
2388
|
-
*
|
|
2389
|
-
*
|
|
2390
|
-
* • Form XObject containing the path (Acrobat)
|
|
2412
|
+
* Tries the new PDFium helper `EPDFAnnot_GetBorderStyle()` (patch series
|
|
2413
|
+
* 9 July 2025).
|
|
2391
2414
|
*
|
|
2392
|
-
* @param
|
|
2393
|
-
* @returns
|
|
2415
|
+
* @param annotationPtr pointer to an `FPDF_ANNOTATION`
|
|
2416
|
+
* @returns `{ ok, style, width }`
|
|
2417
|
+
* • `ok` – `true` when the call succeeded
|
|
2418
|
+
* • `style` – `PdfAnnotationBorderStyle` enum
|
|
2419
|
+
* • `width` – stroke-width in points (defaults to 0 pt)
|
|
2420
|
+
*/
|
|
2421
|
+
getBorderStyle(annotationPtr) {
|
|
2422
|
+
/* 1 ── allocate tmp storage for the returned width ─────────────── */
|
|
2423
|
+
const widthPtr = this.malloc(4);
|
|
2424
|
+
let width = 0;
|
|
2425
|
+
let style = PdfAnnotationBorderStyle.UNKNOWN;
|
|
2426
|
+
let ok = false;
|
|
2427
|
+
style = this.pdfiumModule.EPDFAnnot_GetBorderStyle(annotationPtr, widthPtr);
|
|
2428
|
+
width = this.pdfiumModule.pdfium.getValue(widthPtr, 'float');
|
|
2429
|
+
ok = style !== PdfAnnotationBorderStyle.UNKNOWN;
|
|
2430
|
+
this.free(widthPtr);
|
|
2431
|
+
return { ok, style, width };
|
|
2432
|
+
}
|
|
2433
|
+
setBorderStyle(annotationPtr, style, width) {
|
|
2434
|
+
return this.pdfiumModule.EPDFAnnot_SetBorderStyle(annotationPtr, style, width);
|
|
2435
|
+
}
|
|
2436
|
+
/**
|
|
2437
|
+
* Border-effect (“cloudy”) helper
|
|
2394
2438
|
*
|
|
2395
|
-
*
|
|
2439
|
+
* Calls the new PDFium function `EPDFAnnot_GetBorderEffect()` (July 2025).
|
|
2440
|
+
*
|
|
2441
|
+
* @param annotationPtr pointer to an `FPDF_ANNOTATION`
|
|
2442
|
+
* @returns `{ ok, intensity }`
|
|
2443
|
+
* • `ok` – `true` when the annotation *does* have a
|
|
2444
|
+
* valid cloudy-border effect
|
|
2445
|
+
* • `intensity` – radius/intensity value (0 when `ok` is false)
|
|
2396
2446
|
*/
|
|
2397
|
-
|
|
2398
|
-
const
|
|
2399
|
-
|
|
2400
|
-
|
|
2401
|
-
|
|
2402
|
-
|
|
2403
|
-
const c = this.walkPageObjTree(obj);
|
|
2404
|
-
if (c)
|
|
2405
|
-
return c;
|
|
2406
|
-
}
|
|
2407
|
-
return undefined;
|
|
2447
|
+
getBorderEffect(annotationPtr) {
|
|
2448
|
+
const intensityPtr = this.malloc(4);
|
|
2449
|
+
const ok = !!this.pdfiumModule.EPDFAnnot_GetBorderEffect(annotationPtr, intensityPtr);
|
|
2450
|
+
const intensity = ok ? this.pdfiumModule.pdfium.getValue(intensityPtr, 'float') : 0;
|
|
2451
|
+
this.free(intensityPtr);
|
|
2452
|
+
return { ok, intensity };
|
|
2408
2453
|
}
|
|
2409
|
-
/* --------------------------------------------------------------------------- */
|
|
2410
2454
|
/**
|
|
2411
|
-
*
|
|
2412
|
-
* Squiggly** markup annotations.
|
|
2455
|
+
* Rectangle-differences helper ( /RD array on Square / Circle annots )
|
|
2413
2456
|
*
|
|
2414
|
-
*
|
|
2415
|
-
* 1. `/C` dictionary entry – fast, present in Acrobat / Office PDFs
|
|
2416
|
-
* 2. Appearance-stream objects – drills into paths & nested forms
|
|
2417
|
-
* 3. Hard-coded fallback (Acrobat-style opaque yellow)
|
|
2457
|
+
* Calls `EPDFAnnot_GetRectangleDifferences()` introduced in July 2025.
|
|
2418
2458
|
*
|
|
2419
|
-
* @param
|
|
2420
|
-
* @
|
|
2421
|
-
*
|
|
2459
|
+
* @param annotationPtr pointer to an `FPDF_ANNOTATION`
|
|
2460
|
+
* @returns `{ ok, left, top, right, bottom }`
|
|
2461
|
+
* • `ok` – `true` when the annotation *has* an /RD entry
|
|
2462
|
+
* • the four floats are 0 when `ok` is false
|
|
2463
|
+
*/
|
|
2464
|
+
getRectangleDifferences(annotationPtr) {
|
|
2465
|
+
/* tmp storage ─────────────────────────────────────────── */
|
|
2466
|
+
const lPtr = this.malloc(4);
|
|
2467
|
+
const tPtr = this.malloc(4);
|
|
2468
|
+
const rPtr = this.malloc(4);
|
|
2469
|
+
const bPtr = this.malloc(4);
|
|
2470
|
+
const ok = !!this.pdfiumModule.EPDFAnnot_GetRectangleDifferences(annotationPtr, lPtr, tPtr, rPtr, bPtr);
|
|
2471
|
+
const pdf = this.pdfiumModule.pdfium;
|
|
2472
|
+
const left = pdf.getValue(lPtr, 'float');
|
|
2473
|
+
const top = pdf.getValue(tPtr, 'float');
|
|
2474
|
+
const right = pdf.getValue(rPtr, 'float');
|
|
2475
|
+
const bottom = pdf.getValue(bPtr, 'float');
|
|
2476
|
+
/* cleanup ─────────────────────────────────────────────── */
|
|
2477
|
+
this.free(lPtr);
|
|
2478
|
+
this.free(tPtr);
|
|
2479
|
+
this.free(rPtr);
|
|
2480
|
+
this.free(bPtr);
|
|
2481
|
+
return { ok, left, top, right, bottom };
|
|
2482
|
+
}
|
|
2483
|
+
/**
|
|
2484
|
+
* Dash-pattern helper ( /BS → /D array, dashed borders only )
|
|
2422
2485
|
*
|
|
2423
|
-
*
|
|
2486
|
+
* Uses the two new PDFium helpers:
|
|
2487
|
+
* • `EPDFAnnot_GetBorderDashPatternCount`
|
|
2488
|
+
* • `EPDFAnnot_GetBorderDashPattern`
|
|
2489
|
+
*
|
|
2490
|
+
* @param annotationPtr pointer to an `FPDF_ANNOTATION`
|
|
2491
|
+
* @returns `{ ok, pattern }`
|
|
2492
|
+
* • `ok` – `true` when the annot is dashed *and* the array
|
|
2493
|
+
* was retrieved successfully
|
|
2494
|
+
* • `pattern` – numeric array of dash/space lengths (empty when `ok` is false)
|
|
2424
2495
|
*/
|
|
2425
|
-
|
|
2426
|
-
|
|
2427
|
-
|
|
2428
|
-
|
|
2429
|
-
|
|
2496
|
+
getBorderDashPattern(annotationPtr) {
|
|
2497
|
+
const count = this.pdfiumModule.EPDFAnnot_GetBorderDashPatternCount(annotationPtr);
|
|
2498
|
+
if (count === 0) {
|
|
2499
|
+
return { ok: false, pattern: [] };
|
|
2500
|
+
}
|
|
2501
|
+
/* allocate `count` floats on the WASM heap */
|
|
2502
|
+
const arrPtr = this.malloc(4 * count);
|
|
2503
|
+
const okNative = !!this.pdfiumModule.EPDFAnnot_GetBorderDashPattern(annotationPtr, arrPtr, count);
|
|
2504
|
+
/* copy out */
|
|
2505
|
+
const pattern = [];
|
|
2506
|
+
if (okNative) {
|
|
2507
|
+
const pdf = this.pdfiumModule.pdfium;
|
|
2508
|
+
for (let i = 0; i < count; i++) {
|
|
2509
|
+
pattern.push(pdf.getValue(arrPtr + 4 * i, 'float'));
|
|
2510
|
+
}
|
|
2511
|
+
}
|
|
2512
|
+
this.free(arrPtr);
|
|
2513
|
+
return { ok: okNative, pattern };
|
|
2430
2514
|
}
|
|
2431
2515
|
/**
|
|
2432
2516
|
* Read `/QuadPoints` from any annotation and convert each quadrilateral to
|
|
@@ -2439,11 +2523,11 @@ class PdfiumEngine {
|
|
|
2439
2523
|
*
|
|
2440
2524
|
* @param page - logical page info object (`PdfPageObject`)
|
|
2441
2525
|
* @param annotationPtr - pointer to the annotation whose quads are needed
|
|
2442
|
-
* @returns Array of `
|
|
2526
|
+
* @returns Array of `Rect` objects (`[]` if the annotation has no quads)
|
|
2443
2527
|
*
|
|
2444
2528
|
* @private
|
|
2445
2529
|
*/
|
|
2446
|
-
|
|
2530
|
+
getQuadPointsAnno(page, annotationPtr) {
|
|
2447
2531
|
const quadCount = this.pdfiumModule.FPDFAnnot_CountAttachmentPoints(annotationPtr);
|
|
2448
2532
|
if (quadCount === 0)
|
|
2449
2533
|
return [];
|
|
@@ -2470,7 +2554,116 @@ class PdfiumEngine {
|
|
|
2470
2554
|
}
|
|
2471
2555
|
this.free(quadPtr);
|
|
2472
2556
|
}
|
|
2473
|
-
return quads;
|
|
2557
|
+
return quads.map(quadToRect);
|
|
2558
|
+
}
|
|
2559
|
+
/**
|
|
2560
|
+
* Set the quadrilaterals for a **Highlight / Underline / StrikeOut / Squiggly** markup annotation.
|
|
2561
|
+
*
|
|
2562
|
+
* @param page - logical page info object (`PdfPageObject`)
|
|
2563
|
+
* @param annotationPtr - pointer to the annotation whose quads are needed
|
|
2564
|
+
* @param rects - array of `Rect` objects (`[]` if the annotation has no quads)
|
|
2565
|
+
* @returns `true` if the operation was successful
|
|
2566
|
+
*
|
|
2567
|
+
* @private
|
|
2568
|
+
*/
|
|
2569
|
+
syncQuadPointsAnno(page, annotPtr, rects) {
|
|
2570
|
+
const FS_QUADPOINTSF_SIZE = 8 * 4; // eight floats, 32 bytes
|
|
2571
|
+
const pdf = this.pdfiumModule.pdfium;
|
|
2572
|
+
const count = this.pdfiumModule.FPDFAnnot_CountAttachmentPoints(annotPtr);
|
|
2573
|
+
const buf = this.malloc(FS_QUADPOINTSF_SIZE);
|
|
2574
|
+
/** write one quad into `buf` in annotation space */
|
|
2575
|
+
const writeQuad = (r) => {
|
|
2576
|
+
const q = rectToQuad(r); // TL, TR, BR, BL
|
|
2577
|
+
const p1 = this.convertDevicePointToPagePoint(page, q.p1);
|
|
2578
|
+
const p2 = this.convertDevicePointToPagePoint(page, q.p2);
|
|
2579
|
+
const p3 = this.convertDevicePointToPagePoint(page, q.p3); // BR
|
|
2580
|
+
const p4 = this.convertDevicePointToPagePoint(page, q.p4); // BL
|
|
2581
|
+
// PDF QuadPoints order: BL, BR, TL, TR (bottom-left, bottom-right, top-left, top-right)
|
|
2582
|
+
pdf.setValue(buf + 0, p1.x, 'float'); // BL (bottom-left)
|
|
2583
|
+
pdf.setValue(buf + 4, p1.y, 'float');
|
|
2584
|
+
pdf.setValue(buf + 8, p2.x, 'float'); // BR (bottom-right)
|
|
2585
|
+
pdf.setValue(buf + 12, p2.y, 'float');
|
|
2586
|
+
pdf.setValue(buf + 16, p4.x, 'float'); // TL (top-left)
|
|
2587
|
+
pdf.setValue(buf + 20, p4.y, 'float');
|
|
2588
|
+
pdf.setValue(buf + 24, p3.x, 'float'); // TR (top-right)
|
|
2589
|
+
pdf.setValue(buf + 28, p3.y, 'float');
|
|
2590
|
+
};
|
|
2591
|
+
/* ----------------------------------------------------------------------- */
|
|
2592
|
+
/* 1. overwrite the quads that already exist */
|
|
2593
|
+
const min = Math.min(count, rects.length);
|
|
2594
|
+
for (let i = 0; i < min; i++) {
|
|
2595
|
+
writeQuad(rects[i]);
|
|
2596
|
+
if (!this.pdfiumModule.FPDFAnnot_SetAttachmentPoints(annotPtr, i, buf)) {
|
|
2597
|
+
this.free(buf);
|
|
2598
|
+
return false;
|
|
2599
|
+
}
|
|
2600
|
+
}
|
|
2601
|
+
/* 2. append new quads if rects.length > count */
|
|
2602
|
+
for (let i = count; i < rects.length; i++) {
|
|
2603
|
+
writeQuad(rects[i]);
|
|
2604
|
+
if (!this.pdfiumModule.FPDFAnnot_AppendAttachmentPoints(annotPtr, buf)) {
|
|
2605
|
+
this.free(buf);
|
|
2606
|
+
return false;
|
|
2607
|
+
}
|
|
2608
|
+
}
|
|
2609
|
+
this.free(buf);
|
|
2610
|
+
return true;
|
|
2611
|
+
}
|
|
2612
|
+
/**
|
|
2613
|
+
* Read ink list from annotation
|
|
2614
|
+
* @param page - logical page info object (`PdfPageObject`)
|
|
2615
|
+
* @param annotationPtr - pointer to the annotation whose ink list is needed
|
|
2616
|
+
* @returns ink list
|
|
2617
|
+
*/
|
|
2618
|
+
getInkList(page, annotationPtr) {
|
|
2619
|
+
const inkList = [];
|
|
2620
|
+
const count = this.pdfiumModule.FPDFAnnot_GetInkListCount(annotationPtr);
|
|
2621
|
+
for (let i = 0; i < count; i++) {
|
|
2622
|
+
const points = [];
|
|
2623
|
+
const pointsCount = this.pdfiumModule.FPDFAnnot_GetInkListPath(annotationPtr, i, 0, 0);
|
|
2624
|
+
if (pointsCount > 0) {
|
|
2625
|
+
const pointMemorySize = 8;
|
|
2626
|
+
const pointsPtr = this.malloc(pointsCount * pointMemorySize);
|
|
2627
|
+
this.pdfiumModule.FPDFAnnot_GetInkListPath(annotationPtr, i, pointsPtr, pointsCount);
|
|
2628
|
+
for (let j = 0; j < pointsCount; j++) {
|
|
2629
|
+
const pointX = this.pdfiumModule.pdfium.getValue(pointsPtr + j * 8, 'float');
|
|
2630
|
+
const pointY = this.pdfiumModule.pdfium.getValue(pointsPtr + j * 8 + 4, 'float');
|
|
2631
|
+
const { x, y } = this.convertPagePointToDevicePoint(page, {
|
|
2632
|
+
x: pointX,
|
|
2633
|
+
y: pointY,
|
|
2634
|
+
});
|
|
2635
|
+
points.push({ x, y });
|
|
2636
|
+
}
|
|
2637
|
+
this.free(pointsPtr);
|
|
2638
|
+
}
|
|
2639
|
+
inkList.push({ points });
|
|
2640
|
+
}
|
|
2641
|
+
return inkList;
|
|
2642
|
+
}
|
|
2643
|
+
/**
|
|
2644
|
+
* Add ink list to annotation
|
|
2645
|
+
* @param page - logical page info object (`PdfPageObject`)
|
|
2646
|
+
* @param annotationPtr - pointer to the annotation whose ink list is needed
|
|
2647
|
+
* @param annotation - annotation object (`PdfInkAnnoObject`)
|
|
2648
|
+
* @returns `true` if the operation was successful
|
|
2649
|
+
*/
|
|
2650
|
+
setInkList(page, annotationPtr, inkList) {
|
|
2651
|
+
for (const inkStroke of inkList) {
|
|
2652
|
+
const inkPointsCount = inkStroke.points.length;
|
|
2653
|
+
const inkPointsPtr = this.malloc(inkPointsCount * 8);
|
|
2654
|
+
for (let i = 0; i < inkPointsCount; i++) {
|
|
2655
|
+
const point = inkStroke.points[i];
|
|
2656
|
+
const { x, y } = this.convertDevicePointToPagePoint(page, point);
|
|
2657
|
+
this.pdfiumModule.pdfium.setValue(inkPointsPtr + i * 8, x, 'float');
|
|
2658
|
+
this.pdfiumModule.pdfium.setValue(inkPointsPtr + i * 8 + 4, y, 'float');
|
|
2659
|
+
}
|
|
2660
|
+
if (this.pdfiumModule.FPDFAnnot_AddInkStroke(annotationPtr, inkPointsPtr, inkPointsCount) === -1) {
|
|
2661
|
+
this.free(inkPointsPtr);
|
|
2662
|
+
return false;
|
|
2663
|
+
}
|
|
2664
|
+
this.free(inkPointsPtr);
|
|
2665
|
+
}
|
|
2666
|
+
return true;
|
|
2474
2667
|
}
|
|
2475
2668
|
/**
|
|
2476
2669
|
* Read pdf text annotation
|
|
@@ -2483,30 +2676,23 @@ class PdfiumEngine {
|
|
|
2483
2676
|
* @private
|
|
2484
2677
|
*/
|
|
2485
2678
|
readPdfTextAnno(page, pagePtr, annotationPtr, index) {
|
|
2486
|
-
const appearances = this.readPageAnnoAppearanceStreams(annotationPtr);
|
|
2487
2679
|
const annoRect = this.readPageAnnoRect(annotationPtr);
|
|
2488
2680
|
const rect = this.convertPageRectToDeviceRect(page, pagePtr, annoRect);
|
|
2489
2681
|
const author = this.getAnnotString(annotationPtr, 'T');
|
|
2490
2682
|
const modifiedRaw = this.getAnnotString(annotationPtr, 'M');
|
|
2491
|
-
const modified =
|
|
2683
|
+
const modified = pdfDateToDate(modifiedRaw);
|
|
2492
2684
|
const contents = this.getAnnotString(annotationPtr, 'Contents') || '';
|
|
2493
2685
|
const state = this.getAnnotString(annotationPtr, 'State');
|
|
2494
2686
|
const stateModel = this.getAnnotString(annotationPtr, 'StateModel');
|
|
2495
|
-
const
|
|
2687
|
+
const webAlphaColor = this.resolveAnnotationColor(annotationPtr);
|
|
2496
2688
|
const inReplyToId = this.getInReplyToId(pagePtr, annotationPtr);
|
|
2497
|
-
const popup = !inReplyToId
|
|
2498
|
-
? this.readPdfAnnoLinkedPopup(page, pagePtr, annotationPtr, index)
|
|
2499
|
-
: undefined;
|
|
2500
2689
|
return {
|
|
2501
|
-
status: PdfAnnotationObjectStatus.Committed,
|
|
2502
2690
|
pageIndex: page.index,
|
|
2503
2691
|
id: index,
|
|
2504
2692
|
type: PdfAnnotationSubtype.TEXT,
|
|
2505
2693
|
contents,
|
|
2506
|
-
|
|
2694
|
+
...webAlphaColor,
|
|
2507
2695
|
rect,
|
|
2508
|
-
popup,
|
|
2509
|
-
appearances,
|
|
2510
2696
|
inReplyToId,
|
|
2511
2697
|
author,
|
|
2512
2698
|
modified,
|
|
@@ -2525,16 +2711,13 @@ class PdfiumEngine {
|
|
|
2525
2711
|
* @private
|
|
2526
2712
|
*/
|
|
2527
2713
|
readPdfFreeTextAnno(page, pagePtr, annotationPtr, index) {
|
|
2528
|
-
const appearances = this.readPageAnnoAppearanceStreams(annotationPtr);
|
|
2529
2714
|
const annoRect = this.readPageAnnoRect(annotationPtr);
|
|
2530
2715
|
const rect = this.convertPageRectToDeviceRect(page, pagePtr, annoRect);
|
|
2531
2716
|
const contents = this.getAnnotString(annotationPtr, 'Contents') || '';
|
|
2532
2717
|
const author = this.getAnnotString(annotationPtr, 'T');
|
|
2533
2718
|
const modifiedRaw = this.getAnnotString(annotationPtr, 'M');
|
|
2534
|
-
const modified =
|
|
2535
|
-
const popup = this.readPdfAnnoLinkedPopup(page, pagePtr, annotationPtr, index);
|
|
2719
|
+
const modified = pdfDateToDate(modifiedRaw);
|
|
2536
2720
|
return {
|
|
2537
|
-
status: PdfAnnotationObjectStatus.Committed,
|
|
2538
2721
|
pageIndex: page.index,
|
|
2539
2722
|
id: index,
|
|
2540
2723
|
type: PdfAnnotationSubtype.FREETEXT,
|
|
@@ -2542,8 +2725,6 @@ class PdfiumEngine {
|
|
|
2542
2725
|
author,
|
|
2543
2726
|
modified,
|
|
2544
2727
|
rect,
|
|
2545
|
-
popup,
|
|
2546
|
-
appearances,
|
|
2547
2728
|
};
|
|
2548
2729
|
}
|
|
2549
2730
|
/**
|
|
@@ -2563,13 +2744,12 @@ class PdfiumEngine {
|
|
|
2563
2744
|
if (!linkPtr) {
|
|
2564
2745
|
return;
|
|
2565
2746
|
}
|
|
2566
|
-
const appearances = this.readPageAnnoAppearanceStreams(annotationPtr);
|
|
2567
2747
|
const annoRect = this.readPageAnnoRect(annotationPtr);
|
|
2568
2748
|
const { left, top, right, bottom } = annoRect;
|
|
2569
2749
|
const rect = this.convertPageRectToDeviceRect(page, pagePtr, annoRect);
|
|
2570
2750
|
const author = this.getAnnotString(annotationPtr, 'T');
|
|
2571
2751
|
const modifiedRaw = this.getAnnotString(annotationPtr, 'M');
|
|
2572
|
-
const modified =
|
|
2752
|
+
const modified = pdfDateToDate(modifiedRaw);
|
|
2573
2753
|
const utf16Length = this.pdfiumModule.FPDFText_GetBoundedText(textPagePtr, left, top, right, bottom, 0, 0);
|
|
2574
2754
|
const bytesCount = (utf16Length + 1) * 2; // include NIL
|
|
2575
2755
|
const textBufferPtr = this.malloc(bytesCount);
|
|
@@ -2581,17 +2761,13 @@ class PdfiumEngine {
|
|
|
2581
2761
|
}, () => {
|
|
2582
2762
|
return this.pdfiumModule.FPDFLink_GetDest(docPtr, linkPtr);
|
|
2583
2763
|
});
|
|
2584
|
-
const popup = this.readPdfAnnoLinkedPopup(page, pagePtr, annotationPtr, index);
|
|
2585
2764
|
return {
|
|
2586
|
-
status: PdfAnnotationObjectStatus.Committed,
|
|
2587
2765
|
pageIndex: page.index,
|
|
2588
2766
|
id: index,
|
|
2589
2767
|
type: PdfAnnotationSubtype.LINK,
|
|
2590
2768
|
text,
|
|
2591
2769
|
target,
|
|
2592
2770
|
rect,
|
|
2593
|
-
popup,
|
|
2594
|
-
appearances,
|
|
2595
2771
|
author,
|
|
2596
2772
|
modified,
|
|
2597
2773
|
};
|
|
@@ -2608,23 +2784,18 @@ class PdfiumEngine {
|
|
|
2608
2784
|
* @private
|
|
2609
2785
|
*/
|
|
2610
2786
|
readPdfWidgetAnno(page, pagePtr, annotationPtr, formHandle, index) {
|
|
2611
|
-
const appearances = this.readPageAnnoAppearanceStreams(annotationPtr);
|
|
2612
2787
|
const pageRect = this.readPageAnnoRect(annotationPtr);
|
|
2613
2788
|
const rect = this.convertPageRectToDeviceRect(page, pagePtr, pageRect);
|
|
2614
2789
|
const author = this.getAnnotString(annotationPtr, 'T');
|
|
2615
2790
|
const modifiedRaw = this.getAnnotString(annotationPtr, 'M');
|
|
2616
|
-
const modified =
|
|
2617
|
-
const popup = this.readPdfAnnoLinkedPopup(page, pagePtr, annotationPtr, index);
|
|
2791
|
+
const modified = pdfDateToDate(modifiedRaw);
|
|
2618
2792
|
const field = this.readPdfWidgetAnnoField(formHandle, annotationPtr);
|
|
2619
2793
|
return {
|
|
2620
|
-
status: PdfAnnotationObjectStatus.Committed,
|
|
2621
2794
|
pageIndex: page.index,
|
|
2622
2795
|
id: index,
|
|
2623
2796
|
type: PdfAnnotationSubtype.WIDGET,
|
|
2624
2797
|
rect,
|
|
2625
2798
|
field,
|
|
2626
|
-
popup,
|
|
2627
|
-
appearances,
|
|
2628
2799
|
author,
|
|
2629
2800
|
modified,
|
|
2630
2801
|
};
|
|
@@ -2640,21 +2811,16 @@ class PdfiumEngine {
|
|
|
2640
2811
|
* @private
|
|
2641
2812
|
*/
|
|
2642
2813
|
readPdfFileAttachmentAnno(page, pagePtr, annotationPtr, index) {
|
|
2643
|
-
const appearances = this.readPageAnnoAppearanceStreams(annotationPtr);
|
|
2644
2814
|
const pageRect = this.readPageAnnoRect(annotationPtr);
|
|
2645
2815
|
const rect = this.convertPageRectToDeviceRect(page, pagePtr, pageRect);
|
|
2646
2816
|
const author = this.getAnnotString(annotationPtr, 'T');
|
|
2647
2817
|
const modifiedRaw = this.getAnnotString(annotationPtr, 'M');
|
|
2648
|
-
const modified =
|
|
2649
|
-
const popup = this.readPdfAnnoLinkedPopup(page, pagePtr, annotationPtr, index);
|
|
2818
|
+
const modified = pdfDateToDate(modifiedRaw);
|
|
2650
2819
|
return {
|
|
2651
|
-
status: PdfAnnotationObjectStatus.Committed,
|
|
2652
2820
|
pageIndex: page.index,
|
|
2653
2821
|
id: index,
|
|
2654
2822
|
type: PdfAnnotationSubtype.FILEATTACHMENT,
|
|
2655
2823
|
rect,
|
|
2656
|
-
popup,
|
|
2657
|
-
appearances,
|
|
2658
2824
|
author,
|
|
2659
2825
|
modified,
|
|
2660
2826
|
};
|
|
@@ -2670,44 +2836,22 @@ class PdfiumEngine {
|
|
|
2670
2836
|
* @private
|
|
2671
2837
|
*/
|
|
2672
2838
|
readPdfInkAnno(page, pagePtr, annotationPtr, index) {
|
|
2673
|
-
const appearances = this.readPageAnnoAppearanceStreams(annotationPtr);
|
|
2674
2839
|
const pageRect = this.readPageAnnoRect(annotationPtr);
|
|
2675
2840
|
const rect = this.convertPageRectToDeviceRect(page, pagePtr, pageRect);
|
|
2676
2841
|
const author = this.getAnnotString(annotationPtr, 'T');
|
|
2677
2842
|
const modifiedRaw = this.getAnnotString(annotationPtr, 'M');
|
|
2678
|
-
const modified =
|
|
2679
|
-
const
|
|
2680
|
-
const
|
|
2681
|
-
const
|
|
2682
|
-
for (let i = 0; i < count; i++) {
|
|
2683
|
-
const points = [];
|
|
2684
|
-
const pointsCount = this.pdfiumModule.FPDFAnnot_GetInkListPath(annotationPtr, i, 0, 0);
|
|
2685
|
-
if (pointsCount > 0) {
|
|
2686
|
-
const pointMemorySize = 8;
|
|
2687
|
-
const pointsPtr = this.malloc(pointsCount * pointMemorySize);
|
|
2688
|
-
this.pdfiumModule.FPDFAnnot_GetInkListPath(annotationPtr, i, pointsPtr, pointsCount);
|
|
2689
|
-
for (let j = 0; j < pointsCount; j++) {
|
|
2690
|
-
const pointX = this.pdfiumModule.pdfium.getValue(pointsPtr + j * 8, 'float');
|
|
2691
|
-
const pointY = this.pdfiumModule.pdfium.getValue(pointsPtr + j * 8 + 4, 'float');
|
|
2692
|
-
const { x, y } = this.convertPagePointToDevicePoint(page, {
|
|
2693
|
-
x: pointX,
|
|
2694
|
-
y: pointY,
|
|
2695
|
-
});
|
|
2696
|
-
points.push({ x, y });
|
|
2697
|
-
}
|
|
2698
|
-
this.free(pointsPtr);
|
|
2699
|
-
}
|
|
2700
|
-
inkList.push({ points });
|
|
2701
|
-
}
|
|
2843
|
+
const modified = pdfDateToDate(modifiedRaw);
|
|
2844
|
+
const webAlphaColor = this.resolveAnnotationColor(annotationPtr);
|
|
2845
|
+
const { width: strokeWidth } = this.getBorderStyle(annotationPtr);
|
|
2846
|
+
const inkList = this.getInkList(page, annotationPtr);
|
|
2702
2847
|
return {
|
|
2703
|
-
status: PdfAnnotationObjectStatus.Committed,
|
|
2704
2848
|
pageIndex: page.index,
|
|
2705
2849
|
id: index,
|
|
2706
2850
|
type: PdfAnnotationSubtype.INK,
|
|
2851
|
+
...webAlphaColor,
|
|
2852
|
+
strokeWidth,
|
|
2707
2853
|
rect,
|
|
2708
|
-
popup,
|
|
2709
2854
|
inkList,
|
|
2710
|
-
appearances,
|
|
2711
2855
|
author,
|
|
2712
2856
|
modified,
|
|
2713
2857
|
};
|
|
@@ -2723,23 +2867,18 @@ class PdfiumEngine {
|
|
|
2723
2867
|
* @private
|
|
2724
2868
|
*/
|
|
2725
2869
|
readPdfPolygonAnno(page, pagePtr, annotationPtr, index) {
|
|
2726
|
-
const appearances = this.readPageAnnoAppearanceStreams(annotationPtr);
|
|
2727
2870
|
const pageRect = this.readPageAnnoRect(annotationPtr);
|
|
2728
2871
|
const rect = this.convertPageRectToDeviceRect(page, pagePtr, pageRect);
|
|
2729
2872
|
const author = this.getAnnotString(annotationPtr, 'T');
|
|
2730
2873
|
const modifiedRaw = this.getAnnotString(annotationPtr, 'M');
|
|
2731
|
-
const modified =
|
|
2732
|
-
const popup = this.readPdfAnnoLinkedPopup(page, pagePtr, annotationPtr, index);
|
|
2874
|
+
const modified = pdfDateToDate(modifiedRaw);
|
|
2733
2875
|
const vertices = this.readPdfAnnoVertices(page, pagePtr, annotationPtr);
|
|
2734
2876
|
return {
|
|
2735
|
-
status: PdfAnnotationObjectStatus.Committed,
|
|
2736
2877
|
pageIndex: page.index,
|
|
2737
2878
|
id: index,
|
|
2738
2879
|
type: PdfAnnotationSubtype.POLYGON,
|
|
2739
2880
|
rect,
|
|
2740
|
-
popup,
|
|
2741
2881
|
vertices,
|
|
2742
|
-
appearances,
|
|
2743
2882
|
author,
|
|
2744
2883
|
modified,
|
|
2745
2884
|
};
|
|
@@ -2755,23 +2894,18 @@ class PdfiumEngine {
|
|
|
2755
2894
|
* @private
|
|
2756
2895
|
*/
|
|
2757
2896
|
readPdfPolylineAnno(page, pagePtr, annotationPtr, index) {
|
|
2758
|
-
const appearances = this.readPageAnnoAppearanceStreams(annotationPtr);
|
|
2759
2897
|
const pageRect = this.readPageAnnoRect(annotationPtr);
|
|
2760
2898
|
const rect = this.convertPageRectToDeviceRect(page, pagePtr, pageRect);
|
|
2761
2899
|
const author = this.getAnnotString(annotationPtr, 'T');
|
|
2762
2900
|
const modifiedRaw = this.getAnnotString(annotationPtr, 'M');
|
|
2763
|
-
const modified =
|
|
2764
|
-
const popup = this.readPdfAnnoLinkedPopup(page, pagePtr, annotationPtr, index);
|
|
2901
|
+
const modified = pdfDateToDate(modifiedRaw);
|
|
2765
2902
|
const vertices = this.readPdfAnnoVertices(page, pagePtr, annotationPtr);
|
|
2766
2903
|
return {
|
|
2767
|
-
status: PdfAnnotationObjectStatus.Committed,
|
|
2768
2904
|
pageIndex: page.index,
|
|
2769
2905
|
id: index,
|
|
2770
2906
|
type: PdfAnnotationSubtype.POLYLINE,
|
|
2771
2907
|
rect,
|
|
2772
|
-
popup,
|
|
2773
2908
|
vertices,
|
|
2774
|
-
appearances,
|
|
2775
2909
|
author,
|
|
2776
2910
|
modified,
|
|
2777
2911
|
};
|
|
@@ -2787,13 +2921,11 @@ class PdfiumEngine {
|
|
|
2787
2921
|
* @private
|
|
2788
2922
|
*/
|
|
2789
2923
|
readPdfLineAnno(page, pagePtr, annotationPtr, index) {
|
|
2790
|
-
const appearances = this.readPageAnnoAppearanceStreams(annotationPtr);
|
|
2791
2924
|
const pageRect = this.readPageAnnoRect(annotationPtr);
|
|
2792
2925
|
const rect = this.convertPageRectToDeviceRect(page, pagePtr, pageRect);
|
|
2793
2926
|
const author = this.getAnnotString(annotationPtr, 'T');
|
|
2794
2927
|
const modifiedRaw = this.getAnnotString(annotationPtr, 'M');
|
|
2795
|
-
const modified =
|
|
2796
|
-
const popup = this.readPdfAnnoLinkedPopup(page, pagePtr, annotationPtr, index);
|
|
2928
|
+
const modified = pdfDateToDate(modifiedRaw);
|
|
2797
2929
|
const startPointPtr = this.malloc(8);
|
|
2798
2930
|
const endPointPtr = this.malloc(8);
|
|
2799
2931
|
this.pdfiumModule.FPDFAnnot_GetLine(annotationPtr, startPointPtr, endPointPtr);
|
|
@@ -2812,15 +2944,12 @@ class PdfiumEngine {
|
|
|
2812
2944
|
this.free(startPointPtr);
|
|
2813
2945
|
this.free(endPointPtr);
|
|
2814
2946
|
return {
|
|
2815
|
-
status: PdfAnnotationObjectStatus.Committed,
|
|
2816
2947
|
pageIndex: page.index,
|
|
2817
2948
|
id: index,
|
|
2818
2949
|
type: PdfAnnotationSubtype.LINE,
|
|
2819
2950
|
rect,
|
|
2820
|
-
popup,
|
|
2821
2951
|
startPoint,
|
|
2822
2952
|
endPoint,
|
|
2823
|
-
appearances,
|
|
2824
2953
|
author,
|
|
2825
2954
|
modified,
|
|
2826
2955
|
};
|
|
@@ -2836,25 +2965,22 @@ class PdfiumEngine {
|
|
|
2836
2965
|
* @private
|
|
2837
2966
|
*/
|
|
2838
2967
|
readPdfHighlightAnno(page, pagePtr, annotationPtr, index) {
|
|
2839
|
-
const appearances = this.readPageAnnoAppearanceStreams(annotationPtr);
|
|
2840
2968
|
const pageRect = this.readPageAnnoRect(annotationPtr);
|
|
2841
2969
|
const rect = this.convertPageRectToDeviceRect(page, pagePtr, pageRect);
|
|
2842
|
-
const
|
|
2843
|
-
const
|
|
2844
|
-
const popup = this.readPdfAnnoLinkedPopup(page, pagePtr, annotationPtr, index);
|
|
2970
|
+
const segmentRects = this.getQuadPointsAnno(page, annotationPtr);
|
|
2971
|
+
const webAlphaColor = this.resolveAnnotationColor(annotationPtr);
|
|
2845
2972
|
const author = this.getAnnotString(annotationPtr, 'T');
|
|
2846
2973
|
const modifiedRaw = this.getAnnotString(annotationPtr, 'M');
|
|
2847
|
-
const modified =
|
|
2974
|
+
const modified = pdfDateToDate(modifiedRaw);
|
|
2975
|
+
const contents = this.getAnnotString(annotationPtr, 'Contents') || '';
|
|
2848
2976
|
return {
|
|
2849
|
-
status: PdfAnnotationObjectStatus.Committed,
|
|
2850
2977
|
pageIndex: page.index,
|
|
2851
2978
|
id: index,
|
|
2852
2979
|
type: PdfAnnotationSubtype.HIGHLIGHT,
|
|
2853
2980
|
rect,
|
|
2854
|
-
|
|
2855
|
-
|
|
2856
|
-
|
|
2857
|
-
color,
|
|
2981
|
+
contents,
|
|
2982
|
+
segmentRects,
|
|
2983
|
+
...webAlphaColor,
|
|
2858
2984
|
author,
|
|
2859
2985
|
modified,
|
|
2860
2986
|
};
|
|
@@ -2870,21 +2996,22 @@ class PdfiumEngine {
|
|
|
2870
2996
|
* @private
|
|
2871
2997
|
*/
|
|
2872
2998
|
readPdfUnderlineAnno(page, pagePtr, annotationPtr, index) {
|
|
2873
|
-
const appearances = this.readPageAnnoAppearanceStreams(annotationPtr);
|
|
2874
2999
|
const pageRect = this.readPageAnnoRect(annotationPtr);
|
|
2875
3000
|
const rect = this.convertPageRectToDeviceRect(page, pagePtr, pageRect);
|
|
2876
3001
|
const author = this.getAnnotString(annotationPtr, 'T');
|
|
2877
3002
|
const modifiedRaw = this.getAnnotString(annotationPtr, 'M');
|
|
2878
|
-
const modified =
|
|
2879
|
-
const
|
|
3003
|
+
const modified = pdfDateToDate(modifiedRaw);
|
|
3004
|
+
const segmentRects = this.getQuadPointsAnno(page, annotationPtr);
|
|
3005
|
+
const contents = this.getAnnotString(annotationPtr, 'Contents') || '';
|
|
3006
|
+
const webAlphaColor = this.resolveAnnotationColor(annotationPtr);
|
|
2880
3007
|
return {
|
|
2881
|
-
status: PdfAnnotationObjectStatus.Committed,
|
|
2882
3008
|
pageIndex: page.index,
|
|
2883
3009
|
id: index,
|
|
2884
3010
|
type: PdfAnnotationSubtype.UNDERLINE,
|
|
2885
3011
|
rect,
|
|
2886
|
-
|
|
2887
|
-
|
|
3012
|
+
contents,
|
|
3013
|
+
segmentRects,
|
|
3014
|
+
...webAlphaColor,
|
|
2888
3015
|
author,
|
|
2889
3016
|
modified,
|
|
2890
3017
|
};
|
|
@@ -2900,21 +3027,22 @@ class PdfiumEngine {
|
|
|
2900
3027
|
* @private
|
|
2901
3028
|
*/
|
|
2902
3029
|
readPdfStrikeOutAnno(page, pagePtr, annotationPtr, index) {
|
|
2903
|
-
const appearances = this.readPageAnnoAppearanceStreams(annotationPtr);
|
|
2904
3030
|
const pageRect = this.readPageAnnoRect(annotationPtr);
|
|
2905
3031
|
const rect = this.convertPageRectToDeviceRect(page, pagePtr, pageRect);
|
|
2906
3032
|
const author = this.getAnnotString(annotationPtr, 'T');
|
|
2907
3033
|
const modifiedRaw = this.getAnnotString(annotationPtr, 'M');
|
|
2908
|
-
const modified =
|
|
2909
|
-
const
|
|
3034
|
+
const modified = pdfDateToDate(modifiedRaw);
|
|
3035
|
+
const segmentRects = this.getQuadPointsAnno(page, annotationPtr);
|
|
3036
|
+
const contents = this.getAnnotString(annotationPtr, 'Contents') || '';
|
|
3037
|
+
const webAlphaColor = this.resolveAnnotationColor(annotationPtr);
|
|
2910
3038
|
return {
|
|
2911
|
-
status: PdfAnnotationObjectStatus.Committed,
|
|
2912
3039
|
pageIndex: page.index,
|
|
2913
3040
|
id: index,
|
|
2914
3041
|
type: PdfAnnotationSubtype.STRIKEOUT,
|
|
2915
3042
|
rect,
|
|
2916
|
-
|
|
2917
|
-
|
|
3043
|
+
contents,
|
|
3044
|
+
segmentRects,
|
|
3045
|
+
...webAlphaColor,
|
|
2918
3046
|
author,
|
|
2919
3047
|
modified,
|
|
2920
3048
|
};
|
|
@@ -2930,21 +3058,22 @@ class PdfiumEngine {
|
|
|
2930
3058
|
* @private
|
|
2931
3059
|
*/
|
|
2932
3060
|
readPdfSquigglyAnno(page, pagePtr, annotationPtr, index) {
|
|
2933
|
-
const appearances = this.readPageAnnoAppearanceStreams(annotationPtr);
|
|
2934
3061
|
const pageRect = this.readPageAnnoRect(annotationPtr);
|
|
2935
3062
|
const rect = this.convertPageRectToDeviceRect(page, pagePtr, pageRect);
|
|
2936
3063
|
const author = this.getAnnotString(annotationPtr, 'T');
|
|
2937
3064
|
const modifiedRaw = this.getAnnotString(annotationPtr, 'M');
|
|
2938
|
-
const modified =
|
|
2939
|
-
const
|
|
3065
|
+
const modified = pdfDateToDate(modifiedRaw);
|
|
3066
|
+
const segmentRects = this.getQuadPointsAnno(page, annotationPtr);
|
|
3067
|
+
const contents = this.getAnnotString(annotationPtr, 'Contents') || '';
|
|
3068
|
+
const webAlphaColor = this.resolveAnnotationColor(annotationPtr);
|
|
2940
3069
|
return {
|
|
2941
|
-
status: PdfAnnotationObjectStatus.Committed,
|
|
2942
3070
|
pageIndex: page.index,
|
|
2943
3071
|
id: index,
|
|
2944
3072
|
type: PdfAnnotationSubtype.SQUIGGLY,
|
|
2945
3073
|
rect,
|
|
2946
|
-
|
|
2947
|
-
|
|
3074
|
+
contents,
|
|
3075
|
+
segmentRects,
|
|
3076
|
+
...webAlphaColor,
|
|
2948
3077
|
author,
|
|
2949
3078
|
modified,
|
|
2950
3079
|
};
|
|
@@ -2960,21 +3089,16 @@ class PdfiumEngine {
|
|
|
2960
3089
|
* @private
|
|
2961
3090
|
*/
|
|
2962
3091
|
readPdfCaretAnno(page, pagePtr, annotationPtr, index) {
|
|
2963
|
-
const appearances = this.readPageAnnoAppearanceStreams(annotationPtr);
|
|
2964
3092
|
const pageRect = this.readPageAnnoRect(annotationPtr);
|
|
2965
3093
|
const rect = this.convertPageRectToDeviceRect(page, pagePtr, pageRect);
|
|
2966
3094
|
const author = this.getAnnotString(annotationPtr, 'T');
|
|
2967
3095
|
const modifiedRaw = this.getAnnotString(annotationPtr, 'M');
|
|
2968
|
-
const modified =
|
|
2969
|
-
const popup = this.readPdfAnnoLinkedPopup(page, pagePtr, annotationPtr, index);
|
|
3096
|
+
const modified = pdfDateToDate(modifiedRaw);
|
|
2970
3097
|
return {
|
|
2971
|
-
status: PdfAnnotationObjectStatus.Committed,
|
|
2972
3098
|
pageIndex: page.index,
|
|
2973
3099
|
id: index,
|
|
2974
3100
|
type: PdfAnnotationSubtype.CARET,
|
|
2975
3101
|
rect,
|
|
2976
|
-
popup,
|
|
2977
|
-
appearances,
|
|
2978
3102
|
author,
|
|
2979
3103
|
modified,
|
|
2980
3104
|
};
|
|
@@ -2991,13 +3115,11 @@ class PdfiumEngine {
|
|
|
2991
3115
|
* @private
|
|
2992
3116
|
*/
|
|
2993
3117
|
readPdfStampAnno(docPtr, page, pagePtr, annotationPtr, index) {
|
|
2994
|
-
const appearances = this.readPageAnnoAppearanceStreams(annotationPtr);
|
|
2995
3118
|
const pageRect = this.readPageAnnoRect(annotationPtr);
|
|
2996
3119
|
const rect = this.convertPageRectToDeviceRect(page, pagePtr, pageRect);
|
|
2997
3120
|
const author = this.getAnnotString(annotationPtr, 'T');
|
|
2998
3121
|
const modifiedRaw = this.getAnnotString(annotationPtr, 'M');
|
|
2999
|
-
const modified =
|
|
3000
|
-
const popup = this.readPdfAnnoLinkedPopup(page, pagePtr, annotationPtr, index);
|
|
3122
|
+
const modified = pdfDateToDate(modifiedRaw);
|
|
3001
3123
|
const contents = [];
|
|
3002
3124
|
const objectCount = this.pdfiumModule.FPDFAnnot_GetObjectCount(annotationPtr);
|
|
3003
3125
|
for (let i = 0; i < objectCount; i++) {
|
|
@@ -3008,14 +3130,11 @@ class PdfiumEngine {
|
|
|
3008
3130
|
}
|
|
3009
3131
|
}
|
|
3010
3132
|
return {
|
|
3011
|
-
status: PdfAnnotationObjectStatus.Committed,
|
|
3012
3133
|
pageIndex: page.index,
|
|
3013
3134
|
id: index,
|
|
3014
3135
|
type: PdfAnnotationSubtype.STAMP,
|
|
3015
3136
|
rect,
|
|
3016
|
-
popup,
|
|
3017
3137
|
contents,
|
|
3018
|
-
appearances,
|
|
3019
3138
|
author,
|
|
3020
3139
|
modified,
|
|
3021
3140
|
};
|
|
@@ -3184,6 +3303,39 @@ class PdfiumEngine {
|
|
|
3184
3303
|
this.free(matrixPtr);
|
|
3185
3304
|
return { a: 1, b: 0, c: 0, d: 1, e: 0, f: 0 };
|
|
3186
3305
|
}
|
|
3306
|
+
/**
|
|
3307
|
+
* Return the stroke-width declared in the annotation’s /Border or /BS entry.
|
|
3308
|
+
* Falls back to 1 pt when nothing is defined.
|
|
3309
|
+
*
|
|
3310
|
+
* @param annotationPtr - pointer to pdf annotation
|
|
3311
|
+
* @returns stroke-width
|
|
3312
|
+
*
|
|
3313
|
+
* @private
|
|
3314
|
+
*/
|
|
3315
|
+
getStrokeWidth(annotationPtr) {
|
|
3316
|
+
// FPDFAnnot_GetBorder(annot, &hRadius, &vRadius, &borderWidth)
|
|
3317
|
+
const hPtr = this.malloc(4);
|
|
3318
|
+
const vPtr = this.malloc(4);
|
|
3319
|
+
const wPtr = this.malloc(4);
|
|
3320
|
+
const ok = this.pdfiumModule.FPDFAnnot_GetBorder(annotationPtr, hPtr, vPtr, wPtr);
|
|
3321
|
+
const width = ok ? this.pdfiumModule.pdfium.getValue(wPtr, 'float') : 1; // default 1 pt
|
|
3322
|
+
this.free(hPtr);
|
|
3323
|
+
this.free(vPtr);
|
|
3324
|
+
this.free(wPtr);
|
|
3325
|
+
return width;
|
|
3326
|
+
}
|
|
3327
|
+
/**
|
|
3328
|
+
* Fetches the `/F` flag bit-field from an annotation.
|
|
3329
|
+
*
|
|
3330
|
+
* @param annotationPtr pointer to an `FPDF_ANNOTATION`
|
|
3331
|
+
* @returns `{ raw, flags }`
|
|
3332
|
+
* • `raw` – the 32-bit integer returned by PDFium
|
|
3333
|
+
* • `flags` – object with individual booleans
|
|
3334
|
+
*/
|
|
3335
|
+
getAnnotationFlags(annotationPtr) {
|
|
3336
|
+
const rawFlags = this.pdfiumModule.FPDFAnnot_GetFlags(annotationPtr); // number
|
|
3337
|
+
return flagsToNames(rawFlags);
|
|
3338
|
+
}
|
|
3187
3339
|
/**
|
|
3188
3340
|
* Read circle annotation
|
|
3189
3341
|
* @param page - pdf page infor
|
|
@@ -3195,23 +3347,51 @@ class PdfiumEngine {
|
|
|
3195
3347
|
* @private
|
|
3196
3348
|
*/
|
|
3197
3349
|
readPdfCircleAnno(page, pagePtr, annotationPtr, index) {
|
|
3198
|
-
const
|
|
3350
|
+
const flags = this.getAnnotationFlags(annotationPtr);
|
|
3199
3351
|
const pageRect = this.readPageAnnoRect(annotationPtr);
|
|
3200
3352
|
const rect = this.convertPageRectToDeviceRect(page, pagePtr, pageRect);
|
|
3201
3353
|
const author = this.getAnnotString(annotationPtr, 'T');
|
|
3202
3354
|
const modifiedRaw = this.getAnnotString(annotationPtr, 'M');
|
|
3203
|
-
const modified =
|
|
3204
|
-
const
|
|
3355
|
+
const modified = pdfDateToDate(modifiedRaw);
|
|
3356
|
+
const { color, opacity } = this.resolveAnnotationColor(annotationPtr, PdfAnnotationColorType.InteriorColor);
|
|
3357
|
+
const { color: strokeColor } = this.resolveAnnotationColor(annotationPtr);
|
|
3358
|
+
let { style: strokeStyle, width: strokeWidth } = this.getBorderStyle(annotationPtr);
|
|
3359
|
+
let cloudyBorderIntensity;
|
|
3360
|
+
let cloudyBorderInset;
|
|
3361
|
+
if (strokeStyle === PdfAnnotationBorderStyle.CLOUDY ||
|
|
3362
|
+
strokeStyle === PdfAnnotationBorderStyle.UNKNOWN) {
|
|
3363
|
+
const { ok: hasEffect, intensity } = this.getBorderEffect(annotationPtr);
|
|
3364
|
+
if (hasEffect) {
|
|
3365
|
+
cloudyBorderIntensity = intensity;
|
|
3366
|
+
strokeStyle = PdfAnnotationBorderStyle.CLOUDY;
|
|
3367
|
+
const { ok: hasInset, left, top, right, bottom, } = this.getRectangleDifferences(annotationPtr);
|
|
3368
|
+
if (hasInset)
|
|
3369
|
+
cloudyBorderInset = [left, top, right, bottom];
|
|
3370
|
+
}
|
|
3371
|
+
}
|
|
3372
|
+
let strokeDashArray;
|
|
3373
|
+
if (strokeStyle === PdfAnnotationBorderStyle.DASHED) {
|
|
3374
|
+
const { ok, pattern } = this.getBorderDashPattern(annotationPtr);
|
|
3375
|
+
if (ok) {
|
|
3376
|
+
strokeDashArray = pattern;
|
|
3377
|
+
}
|
|
3378
|
+
}
|
|
3205
3379
|
return {
|
|
3206
|
-
status: PdfAnnotationObjectStatus.Committed,
|
|
3207
3380
|
pageIndex: page.index,
|
|
3208
3381
|
id: index,
|
|
3209
3382
|
type: PdfAnnotationSubtype.CIRCLE,
|
|
3383
|
+
flags,
|
|
3384
|
+
color,
|
|
3385
|
+
opacity,
|
|
3386
|
+
strokeWidth,
|
|
3387
|
+
strokeColor,
|
|
3388
|
+
strokeStyle,
|
|
3210
3389
|
rect,
|
|
3211
|
-
popup,
|
|
3212
|
-
appearances,
|
|
3213
3390
|
author,
|
|
3214
3391
|
modified,
|
|
3392
|
+
...(cloudyBorderIntensity !== undefined && { cloudyBorderIntensity }),
|
|
3393
|
+
...(cloudyBorderInset !== undefined && { cloudyBorderInset }),
|
|
3394
|
+
...(strokeDashArray !== undefined && { strokeDashArray }),
|
|
3215
3395
|
};
|
|
3216
3396
|
}
|
|
3217
3397
|
/**
|
|
@@ -3225,23 +3405,51 @@ class PdfiumEngine {
|
|
|
3225
3405
|
* @private
|
|
3226
3406
|
*/
|
|
3227
3407
|
readPdfSquareAnno(page, pagePtr, annotationPtr, index) {
|
|
3228
|
-
const
|
|
3408
|
+
const flags = this.getAnnotationFlags(annotationPtr);
|
|
3229
3409
|
const pageRect = this.readPageAnnoRect(annotationPtr);
|
|
3230
3410
|
const rect = this.convertPageRectToDeviceRect(page, pagePtr, pageRect);
|
|
3231
3411
|
const author = this.getAnnotString(annotationPtr, 'T');
|
|
3232
3412
|
const modifiedRaw = this.getAnnotString(annotationPtr, 'M');
|
|
3233
|
-
const modified =
|
|
3234
|
-
const
|
|
3413
|
+
const modified = pdfDateToDate(modifiedRaw);
|
|
3414
|
+
const { color, opacity } = this.resolveAnnotationColor(annotationPtr, PdfAnnotationColorType.InteriorColor);
|
|
3415
|
+
const { color: strokeColor } = this.resolveAnnotationColor(annotationPtr);
|
|
3416
|
+
let { style: strokeStyle, width: strokeWidth } = this.getBorderStyle(annotationPtr);
|
|
3417
|
+
let cloudyBorderIntensity;
|
|
3418
|
+
let cloudyBorderInset;
|
|
3419
|
+
if (strokeStyle === PdfAnnotationBorderStyle.CLOUDY ||
|
|
3420
|
+
strokeStyle === PdfAnnotationBorderStyle.UNKNOWN) {
|
|
3421
|
+
const { ok: hasEffect, intensity } = this.getBorderEffect(annotationPtr);
|
|
3422
|
+
if (hasEffect) {
|
|
3423
|
+
cloudyBorderIntensity = intensity;
|
|
3424
|
+
strokeStyle = PdfAnnotationBorderStyle.CLOUDY;
|
|
3425
|
+
const { ok: hasInset, left, top, right, bottom, } = this.getRectangleDifferences(annotationPtr);
|
|
3426
|
+
if (hasInset)
|
|
3427
|
+
cloudyBorderInset = [left, top, right, bottom];
|
|
3428
|
+
}
|
|
3429
|
+
}
|
|
3430
|
+
let strokeDashArray;
|
|
3431
|
+
if (strokeStyle === PdfAnnotationBorderStyle.DASHED) {
|
|
3432
|
+
const { ok, pattern } = this.getBorderDashPattern(annotationPtr);
|
|
3433
|
+
if (ok) {
|
|
3434
|
+
strokeDashArray = pattern;
|
|
3435
|
+
}
|
|
3436
|
+
}
|
|
3235
3437
|
return {
|
|
3236
|
-
status: PdfAnnotationObjectStatus.Committed,
|
|
3237
3438
|
pageIndex: page.index,
|
|
3238
3439
|
id: index,
|
|
3239
3440
|
type: PdfAnnotationSubtype.SQUARE,
|
|
3441
|
+
flags,
|
|
3442
|
+
color,
|
|
3443
|
+
opacity,
|
|
3444
|
+
strokeColor,
|
|
3445
|
+
strokeWidth,
|
|
3446
|
+
strokeStyle,
|
|
3240
3447
|
rect,
|
|
3241
|
-
popup,
|
|
3242
|
-
appearances,
|
|
3243
3448
|
author,
|
|
3244
3449
|
modified,
|
|
3450
|
+
...(cloudyBorderIntensity !== undefined && { cloudyBorderIntensity }),
|
|
3451
|
+
...(cloudyBorderInset !== undefined && { cloudyBorderInset }),
|
|
3452
|
+
...(strokeDashArray !== undefined && { strokeDashArray }),
|
|
3245
3453
|
};
|
|
3246
3454
|
}
|
|
3247
3455
|
/**
|
|
@@ -3256,21 +3464,16 @@ class PdfiumEngine {
|
|
|
3256
3464
|
* @private
|
|
3257
3465
|
*/
|
|
3258
3466
|
readPdfAnno(page, pagePtr, type, annotationPtr, index) {
|
|
3259
|
-
const appearances = this.readPageAnnoAppearanceStreams(annotationPtr);
|
|
3260
3467
|
const pageRect = this.readPageAnnoRect(annotationPtr);
|
|
3261
3468
|
const rect = this.convertPageRectToDeviceRect(page, pagePtr, pageRect);
|
|
3262
3469
|
const author = this.getAnnotString(annotationPtr, 'T');
|
|
3263
3470
|
const modifiedRaw = this.getAnnotString(annotationPtr, 'M');
|
|
3264
|
-
const modified =
|
|
3265
|
-
const popup = this.readPdfAnnoLinkedPopup(page, pagePtr, annotationPtr, index);
|
|
3471
|
+
const modified = pdfDateToDate(modifiedRaw);
|
|
3266
3472
|
return {
|
|
3267
|
-
status: PdfAnnotationObjectStatus.Committed,
|
|
3268
3473
|
pageIndex: page.index,
|
|
3269
3474
|
id: index,
|
|
3270
3475
|
type,
|
|
3271
3476
|
rect,
|
|
3272
|
-
popup,
|
|
3273
|
-
appearances,
|
|
3274
3477
|
author,
|
|
3275
3478
|
modified,
|
|
3276
3479
|
};
|
|
@@ -3292,25 +3495,6 @@ class PdfiumEngine {
|
|
|
3292
3495
|
const idx = this.pdfiumModule.FPDFPage_GetAnnotIndex(pagePtr, parentPtr);
|
|
3293
3496
|
return idx >= 0 ? idx : undefined;
|
|
3294
3497
|
}
|
|
3295
|
-
/**
|
|
3296
|
-
* Parse a PDF date string **D:YYYYMMDDHHmmSSOHH'mm'** to ISO-8601.
|
|
3297
|
-
*
|
|
3298
|
-
* Returns `undefined` if the input is malformed.
|
|
3299
|
-
*
|
|
3300
|
-
* @private
|
|
3301
|
-
*/
|
|
3302
|
-
toIsoDate(pdfDate) {
|
|
3303
|
-
if (!pdfDate?.startsWith('D:'))
|
|
3304
|
-
return;
|
|
3305
|
-
// Minimal parse – ignore timezone for brevity
|
|
3306
|
-
const y = pdfDate.substring(2, 6);
|
|
3307
|
-
const m = pdfDate.substring(6, 8) || '01';
|
|
3308
|
-
const d = pdfDate.substring(8, 10) || '01';
|
|
3309
|
-
const H = pdfDate.substring(10, 12) || '00';
|
|
3310
|
-
const M = pdfDate.substring(12, 14) || '00';
|
|
3311
|
-
const S = pdfDate.substring(14, 16) || '00';
|
|
3312
|
-
return `${y}-${m}-${d}T${H}:${M}:${S}`;
|
|
3313
|
-
}
|
|
3314
3498
|
/**
|
|
3315
3499
|
* Fetch a string value (`/T`, `/M`, `/State`, …) from an annotation.
|
|
3316
3500
|
*
|
|
@@ -3330,41 +3514,19 @@ class PdfiumEngine {
|
|
|
3330
3514
|
return value || undefined;
|
|
3331
3515
|
}
|
|
3332
3516
|
/**
|
|
3333
|
-
*
|
|
3334
|
-
*
|
|
3335
|
-
* @
|
|
3336
|
-
* @param annotationPtr - pointer to pdf annotation
|
|
3337
|
-
* @param index - index of annotation in the pdf page
|
|
3338
|
-
* @returns pdf popup linked to annotation
|
|
3517
|
+
* Set a string value (`/T`, `/M`, `/State`, …) to an annotation.
|
|
3518
|
+
*
|
|
3519
|
+
* @returns `true` if the operation was successful
|
|
3339
3520
|
*
|
|
3340
3521
|
* @private
|
|
3341
3522
|
*/
|
|
3342
|
-
|
|
3343
|
-
const
|
|
3344
|
-
const
|
|
3345
|
-
|
|
3346
|
-
|
|
3347
|
-
|
|
3348
|
-
|
|
3349
|
-
const rect = this.convertPageRectToDeviceRect(page, pagePtr, pageRect);
|
|
3350
|
-
const author = this.getAnnotString(annotationPtr, 'T');
|
|
3351
|
-
const modifiedRaw = this.getAnnotString(annotationPtr, 'M');
|
|
3352
|
-
const modified = this.toIsoDate(modifiedRaw);
|
|
3353
|
-
const contents = this.getAnnotString(annotationPtr, 'Contents') || '';
|
|
3354
|
-
const open = this.getAnnotString(annotationPtr, 'Open') || 'false';
|
|
3355
|
-
this.pdfiumModule.FPDFPage_CloseAnnot(popupAnnotationPtr);
|
|
3356
|
-
return {
|
|
3357
|
-
status: PdfAnnotationObjectStatus.Committed,
|
|
3358
|
-
pageIndex: page.index,
|
|
3359
|
-
id: index,
|
|
3360
|
-
type: PdfAnnotationSubtype.POPUP,
|
|
3361
|
-
rect,
|
|
3362
|
-
contents,
|
|
3363
|
-
open: open === 'true',
|
|
3364
|
-
appearances,
|
|
3365
|
-
author,
|
|
3366
|
-
modified,
|
|
3367
|
-
};
|
|
3523
|
+
setAnnotString(annotationPtr, key, value) {
|
|
3524
|
+
const bytes = 2 * (value.length + 1);
|
|
3525
|
+
const ptr = this.malloc(bytes);
|
|
3526
|
+
this.pdfiumModule.pdfium.stringToUTF16(value, ptr, bytes);
|
|
3527
|
+
const ok = this.pdfiumModule.FPDFAnnot_SetStringValue(annotationPtr, key, ptr);
|
|
3528
|
+
this.free(ptr);
|
|
3529
|
+
return ok;
|
|
3368
3530
|
}
|
|
3369
3531
|
/**
|
|
3370
3532
|
* Read vertices of pdf annotation
|
|
@@ -3473,6 +3635,81 @@ class PdfiumEngine {
|
|
|
3473
3635
|
options,
|
|
3474
3636
|
};
|
|
3475
3637
|
}
|
|
3638
|
+
/**
|
|
3639
|
+
* {@inheritDoc @embedpdf/models!PdfEngine.renderAnnotation}
|
|
3640
|
+
*
|
|
3641
|
+
* @public
|
|
3642
|
+
*/
|
|
3643
|
+
renderAnnotation(doc, page, annotation, scaleFactor, rotation, dpr = 1, // device-pixel-ratio (canvas)
|
|
3644
|
+
mode = AppearanceMode.Normal, imageType = 'image/webp') {
|
|
3645
|
+
this.logger.debug(LOG_SOURCE$1, LOG_CATEGORY$1, 'renderAnnotation', doc, page, annotation, scaleFactor, rotation, dpr, mode, imageType);
|
|
3646
|
+
this.logger.perf(LOG_SOURCE$1, LOG_CATEGORY$1, `RenderAnnotation`, 'Begin', `${doc.id}-${page.index}-${annotation.id}`);
|
|
3647
|
+
const task = new Task();
|
|
3648
|
+
const ctx = this.cache.getContext(doc.id);
|
|
3649
|
+
if (!ctx) {
|
|
3650
|
+
this.logger.perf(LOG_SOURCE$1, LOG_CATEGORY$1, `RenderAnnotation`, 'End', `${doc.id}-${page.index}-${annotation.id}`);
|
|
3651
|
+
return PdfTaskHelper.reject({
|
|
3652
|
+
code: PdfErrorCode.DocNotOpen,
|
|
3653
|
+
message: 'document does not open',
|
|
3654
|
+
});
|
|
3655
|
+
}
|
|
3656
|
+
/* ── 1. grab native handles ───────────────────────────────────────── */
|
|
3657
|
+
const pageCtx = ctx.acquirePage(page.index);
|
|
3658
|
+
const annotPtr = this.pdfiumModule.FPDFPage_GetAnnot(pageCtx.pagePtr, annotation.id);
|
|
3659
|
+
if (!annotPtr) {
|
|
3660
|
+
pageCtx.release();
|
|
3661
|
+
this.logger.perf(LOG_SOURCE$1, LOG_CATEGORY$1, `RenderAnnotation`, 'End', `${doc.id}-${page.index}-${annotation.id}`);
|
|
3662
|
+
return PdfTaskHelper.reject({
|
|
3663
|
+
code: PdfErrorCode.NotFound,
|
|
3664
|
+
message: 'annotation not found',
|
|
3665
|
+
});
|
|
3666
|
+
}
|
|
3667
|
+
const finalScale = scaleFactor * dpr;
|
|
3668
|
+
/* ── 2. decide bitmap size (integer pixels) ──────────────────────── */
|
|
3669
|
+
const annotRect = annotation.rect;
|
|
3670
|
+
const bitmapRect = toIntRect(transformRect(page.size, annotRect, rotation, finalScale));
|
|
3671
|
+
const format = BitmapFormat.Bitmap_BGRA;
|
|
3672
|
+
const bytesPerPixel = 4;
|
|
3673
|
+
const bitmapHeapLength = bitmapRect.size.width * bitmapRect.size.height * bytesPerPixel;
|
|
3674
|
+
const bitmapHeapPtr = this.malloc(bitmapHeapLength);
|
|
3675
|
+
const bitmapPtr = this.pdfiumModule.FPDFBitmap_CreateEx(bitmapRect.size.width, bitmapRect.size.height, format, bitmapHeapPtr, bitmapRect.size.width * bytesPerPixel);
|
|
3676
|
+
this.pdfiumModule.FPDFBitmap_FillRect(bitmapPtr, 0, 0, bitmapRect.size.width, bitmapRect.size.height, 0x00000000);
|
|
3677
|
+
const matrix = makeMatrix(annotation.rect, rotation, finalScale);
|
|
3678
|
+
// Allocate memory for the matrix on the wasm heap and write to it
|
|
3679
|
+
const matrixSize = 6 * 4;
|
|
3680
|
+
const matrixPtr = this.malloc(matrixSize);
|
|
3681
|
+
const matrixView = new Float32Array(this.pdfiumModule.pdfium.HEAPF32.buffer, matrixPtr, 6);
|
|
3682
|
+
matrixView.set([matrix.a, matrix.b, matrix.c, matrix.d, matrix.e, matrix.f]);
|
|
3683
|
+
/* ── 5. call the native helper with the new matrix ───────────────── */
|
|
3684
|
+
const FLAGS = RenderFlag.REVERSE_BYTE_ORDER;
|
|
3685
|
+
const ok = !!this.pdfiumModule.EPDF_RenderAnnotBitmap(bitmapPtr, pageCtx.pagePtr, annotPtr, mode, matrixPtr, FLAGS);
|
|
3686
|
+
/* ── 6. tear down native resources ───────────────────────────────── */
|
|
3687
|
+
this.free(matrixPtr); // Free the matrix memory
|
|
3688
|
+
this.pdfiumModule.FPDFBitmap_Destroy(bitmapPtr);
|
|
3689
|
+
this.pdfiumModule.FPDFPage_CloseAnnot(annotPtr);
|
|
3690
|
+
pageCtx.release();
|
|
3691
|
+
if (!ok) {
|
|
3692
|
+
this.free(bitmapHeapPtr);
|
|
3693
|
+
this.logger.perf(LOG_SOURCE$1, LOG_CATEGORY$1, `RenderAnnotation`, 'End', `${doc.id}-${page.index}-${annotation.id}`);
|
|
3694
|
+
return PdfTaskHelper.reject({
|
|
3695
|
+
code: PdfErrorCode.Unknown,
|
|
3696
|
+
message: 'EPDF_RenderAnnotBitmap failed',
|
|
3697
|
+
});
|
|
3698
|
+
}
|
|
3699
|
+
/* ── 6. copy out + convert to Blob (reuse existing converter) ─────── */
|
|
3700
|
+
const data = this.pdfiumModule.pdfium.HEAPU8.subarray(bitmapHeapPtr, bitmapHeapPtr + bitmapHeapLength);
|
|
3701
|
+
const imageData = {
|
|
3702
|
+
data: new Uint8ClampedArray(data),
|
|
3703
|
+
width: bitmapRect.size.width,
|
|
3704
|
+
height: bitmapRect.size.height,
|
|
3705
|
+
};
|
|
3706
|
+
this.free(bitmapHeapPtr);
|
|
3707
|
+
this.logger.perf(LOG_SOURCE$1, LOG_CATEGORY$1, `RenderAnnotation`, 'End', `${doc.id}-${page.index}-${annotation.id}`);
|
|
3708
|
+
this.imageDataConverter(imageData, imageType)
|
|
3709
|
+
.then((blob) => task.resolve(blob))
|
|
3710
|
+
.catch((err) => task.reject({ code: PdfErrorCode.Unknown, message: String(err) }));
|
|
3711
|
+
return task;
|
|
3712
|
+
}
|
|
3476
3713
|
/**
|
|
3477
3714
|
* render rectangle of pdf page to image
|
|
3478
3715
|
* @param docPtr - pointer to pdf document object
|
|
@@ -3805,6 +4042,64 @@ class PdfiumEngine {
|
|
|
3805
4042
|
this.free(bufferPtr);
|
|
3806
4043
|
return ap;
|
|
3807
4044
|
}
|
|
4045
|
+
/**
|
|
4046
|
+
* Change the visible colour (and opacity) of an existing annotation.
|
|
4047
|
+
*
|
|
4048
|
+
* For markup annotations (highlight / underline / strikeout / squiggly) we
|
|
4049
|
+
* first clear the AP dictionary entry, otherwise the stored appearance stream
|
|
4050
|
+
* will override the new tint. For all other sub-types we keep the existing
|
|
4051
|
+
* AP so custom artwork isn't lost.
|
|
4052
|
+
*
|
|
4053
|
+
* @param doc logical document object
|
|
4054
|
+
* @param page logical page object
|
|
4055
|
+
* @param annotation the annotation we want to recolour
|
|
4056
|
+
* @param colour RGBA tuple (0-255 per channel)
|
|
4057
|
+
* @param which 0 = stroke/fill colour (PDFium's "colourType" param)
|
|
4058
|
+
*
|
|
4059
|
+
* @returns `true` when the operation succeeded
|
|
4060
|
+
*/
|
|
4061
|
+
updateAnnotationColor(doc, page, annotation, color, which = 0) {
|
|
4062
|
+
this.logger.debug(LOG_SOURCE$1, LOG_CATEGORY$1, 'setAnnotationColor', doc, page, annotation, color, which);
|
|
4063
|
+
this.logger.perf(LOG_SOURCE$1, LOG_CATEGORY$1, 'setAnnotationColor', 'Begin', doc.id);
|
|
4064
|
+
const task = PdfTaskHelper.create();
|
|
4065
|
+
try {
|
|
4066
|
+
/* 1 ── sanity & native handles ────────────────────────────────────────── */
|
|
4067
|
+
const ctx = this.cache.getContext(doc.id);
|
|
4068
|
+
if (!ctx) {
|
|
4069
|
+
this.logger.perf(LOG_SOURCE$1, LOG_CATEGORY$1, 'setAnnotationColor', 'End', doc.id);
|
|
4070
|
+
this.logger.warn(LOG_SOURCE$1, LOG_CATEGORY$1, 'setAnnotationColor: doc closed');
|
|
4071
|
+
task.resolve(false);
|
|
4072
|
+
return task;
|
|
4073
|
+
}
|
|
4074
|
+
const pageCtx = ctx.acquirePage(page.index);
|
|
4075
|
+
const annotPtr = this.pdfiumModule.FPDFPage_GetAnnot(pageCtx.pagePtr, annotation.id);
|
|
4076
|
+
if (!annotPtr) {
|
|
4077
|
+
this.logger.perf(LOG_SOURCE$1, LOG_CATEGORY$1, 'setAnnotationColor', 'End', doc.id);
|
|
4078
|
+
this.logger.warn(LOG_SOURCE$1, LOG_CATEGORY$1, 'setAnnotationColor: annot not found');
|
|
4079
|
+
pageCtx.release();
|
|
4080
|
+
task.resolve(false);
|
|
4081
|
+
return task;
|
|
4082
|
+
}
|
|
4083
|
+
const ok = this.setAnnotationColor(annotPtr, color, which);
|
|
4084
|
+
/* 4 ── regenerate appearance & clean-up ───────────────────────────────── */
|
|
4085
|
+
if (ok) {
|
|
4086
|
+
this.pdfiumModule.FPDFPage_GenerateContent(pageCtx.pagePtr);
|
|
4087
|
+
}
|
|
4088
|
+
this.pdfiumModule.FPDFPage_CloseAnnot(annotPtr);
|
|
4089
|
+
pageCtx.release();
|
|
4090
|
+
this.logger.perf(LOG_SOURCE$1, LOG_CATEGORY$1, 'setAnnotationColor', 'End', doc.id);
|
|
4091
|
+
task.resolve(!!ok);
|
|
4092
|
+
}
|
|
4093
|
+
catch (error) {
|
|
4094
|
+
this.logger.perf(LOG_SOURCE$1, LOG_CATEGORY$1, 'setAnnotationColor', 'End', doc.id);
|
|
4095
|
+
this.logger.error(LOG_SOURCE$1, LOG_CATEGORY$1, 'setAnnotationColor: error', error);
|
|
4096
|
+
task.reject({
|
|
4097
|
+
code: PdfErrorCode.Unknown,
|
|
4098
|
+
message: `Failed to set annotation color: ${error instanceof Error ? error.message : String(error)}`,
|
|
4099
|
+
});
|
|
4100
|
+
}
|
|
4101
|
+
return task;
|
|
4102
|
+
}
|
|
3808
4103
|
/**
|
|
3809
4104
|
* Set the rect of specified annotation
|
|
3810
4105
|
* @param page - page info that the annotation is belonged to
|
|
@@ -4140,7 +4435,7 @@ class EngineRunner {
|
|
|
4140
4435
|
type: 'reject',
|
|
4141
4436
|
reason: {
|
|
4142
4437
|
code: PdfErrorCode.NotSupport,
|
|
4143
|
-
message:
|
|
4438
|
+
message: `engine method ${name} is not supported yet`,
|
|
4144
4439
|
},
|
|
4145
4440
|
};
|
|
4146
4441
|
const response = {
|
|
@@ -4195,6 +4490,9 @@ class EngineRunner {
|
|
|
4195
4490
|
case 'renderPageRect':
|
|
4196
4491
|
task = this.engine[name](...args);
|
|
4197
4492
|
break;
|
|
4493
|
+
case 'renderAnnotation':
|
|
4494
|
+
task = this.engine[name](...args);
|
|
4495
|
+
break;
|
|
4198
4496
|
case 'renderThumbnail':
|
|
4199
4497
|
task = this.engine[name](...args);
|
|
4200
4498
|
break;
|
|
@@ -4207,12 +4505,15 @@ class EngineRunner {
|
|
|
4207
4505
|
case 'createPageAnnotation':
|
|
4208
4506
|
task = this.engine[name](...args);
|
|
4209
4507
|
break;
|
|
4210
|
-
case '
|
|
4508
|
+
case 'updatePageAnnotation':
|
|
4211
4509
|
task = this.engine[name](...args);
|
|
4212
4510
|
break;
|
|
4213
4511
|
case 'removePageAnnotation':
|
|
4214
4512
|
task = this.engine[name](...args);
|
|
4215
4513
|
break;
|
|
4514
|
+
case 'updateAnnotationColor':
|
|
4515
|
+
task = this.engine[name](...args);
|
|
4516
|
+
break;
|
|
4216
4517
|
case 'getPageTextRects':
|
|
4217
4518
|
task = this.engine[name](...args);
|
|
4218
4519
|
break;
|