@embedpdf/plugin-annotation 2.13.0 → 2.14.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +1 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +449 -1
- package/dist/index.js.map +1 -1
- package/dist/lib/handlers/callout-free-text.handler.d.ts +3 -0
- package/dist/lib/handlers/index.d.ts +1 -0
- package/dist/lib/handlers/types.d.ts +7 -1
- package/dist/lib/patching/patch-utils.d.ts +38 -1
- package/dist/lib/patching/patches/callout-freetext.patch.d.ts +3 -0
- package/dist/lib/patching/patches/index.d.ts +1 -0
- package/dist/lib/tools/default-tools.d.ts +35 -0
- package/dist/preact/index.cjs +1 -1
- package/dist/preact/index.cjs.map +1 -1
- package/dist/preact/index.js +395 -14
- package/dist/preact/index.js.map +1 -1
- package/dist/react/index.cjs +1 -1
- package/dist/react/index.cjs.map +1 -1
- package/dist/react/index.js +395 -14
- package/dist/react/index.js.map +1 -1
- package/dist/shared/components/annotations/callout-free-text-preview.d.ts +15 -0
- package/dist/shared/components/annotations/callout-free-text.d.ts +15 -0
- package/dist/shared-preact/components/annotations/callout-free-text-preview.d.ts +15 -0
- package/dist/shared-preact/components/annotations/callout-free-text.d.ts +15 -0
- package/dist/shared-react/components/annotations/callout-free-text-preview.d.ts +15 -0
- package/dist/shared-react/components/annotations/callout-free-text.d.ts +15 -0
- package/dist/svelte/components/annotations/CalloutFreeText.svelte.d.ts +15 -0
- package/dist/svelte/components/annotations/CalloutFreeTextPreview.svelte.d.ts +10 -0
- package/dist/svelte/components/renderers/CalloutFreeTextRenderer.svelte.d.ts +5 -0
- package/dist/svelte/index.cjs +1 -1
- package/dist/svelte/index.cjs.map +1 -1
- package/dist/svelte/index.js +497 -86
- package/dist/svelte/index.js.map +1 -1
- package/dist/vue/components/annotations/callout-free-text-preview.vue.d.ts +10 -0
- package/dist/vue/components/annotations/callout-free-text.vue.d.ts +25 -0
- package/dist/vue/components/renderers/callout-free-text-renderer.vue.d.ts +6 -0
- package/dist/vue/index.cjs +1 -1
- package/dist/vue/index.cjs.map +1 -1
- package/dist/vue/index.js +544 -170
- package/dist/vue/index.js.map +1 -1
- package/package.json +12 -12
package/dist/index.js
CHANGED
|
@@ -737,6 +737,109 @@ function compensateRotatedVertexEdit(original, vertices, tightRect) {
|
|
|
737
737
|
if (Math.abs(qx) < 1e-8 && Math.abs(qy) < 1e-8) return vertices;
|
|
738
738
|
return vertices.map((v) => ({ x: v.x + qx, y: v.y + qy }));
|
|
739
739
|
}
|
|
740
|
+
function computeTextBoxFromRD(rect, rd) {
|
|
741
|
+
if (!rd) return rect;
|
|
742
|
+
return {
|
|
743
|
+
origin: { x: rect.origin.x + rd.left, y: rect.origin.y + rd.top },
|
|
744
|
+
size: {
|
|
745
|
+
width: Math.max(0, rect.size.width - rd.left - rd.right),
|
|
746
|
+
height: Math.max(0, rect.size.height - rd.top - rd.bottom)
|
|
747
|
+
}
|
|
748
|
+
};
|
|
749
|
+
}
|
|
750
|
+
function computeRDFromTextBox(overallRect, textBox) {
|
|
751
|
+
return {
|
|
752
|
+
left: textBox.origin.x - overallRect.origin.x,
|
|
753
|
+
top: textBox.origin.y - overallRect.origin.y,
|
|
754
|
+
right: overallRect.origin.x + overallRect.size.width - (textBox.origin.x + textBox.size.width),
|
|
755
|
+
bottom: overallRect.origin.y + overallRect.size.height - (textBox.origin.y + textBox.size.height)
|
|
756
|
+
};
|
|
757
|
+
}
|
|
758
|
+
function computeCalloutConnectionPoint(knee, textBox) {
|
|
759
|
+
const cx = textBox.origin.x + textBox.size.width / 2;
|
|
760
|
+
const cy = textBox.origin.y + textBox.size.height / 2;
|
|
761
|
+
const dx = knee.x - cx;
|
|
762
|
+
const dy = knee.y - cy;
|
|
763
|
+
if (Math.abs(dx) >= Math.abs(dy)) {
|
|
764
|
+
return dx > 0 ? { x: textBox.origin.x + textBox.size.width, y: cy } : { x: textBox.origin.x, y: cy };
|
|
765
|
+
}
|
|
766
|
+
return dy > 0 ? { x: cx, y: textBox.origin.y + textBox.size.height } : { x: cx, y: textBox.origin.y };
|
|
767
|
+
}
|
|
768
|
+
function computeCalloutOverallRect(textBox, calloutLine, lineEnding, strokeWidth) {
|
|
769
|
+
const linePoints = [...calloutLine];
|
|
770
|
+
if (lineEnding && calloutLine.length >= 2) {
|
|
771
|
+
const handler = LINE_ENDING_HANDLERS[lineEnding];
|
|
772
|
+
if (handler) {
|
|
773
|
+
const angle = Math.atan2(
|
|
774
|
+
calloutLine[1].y - calloutLine[0].y,
|
|
775
|
+
calloutLine[1].x - calloutLine[0].x
|
|
776
|
+
);
|
|
777
|
+
const localPts = handler.getLocalPoints(strokeWidth);
|
|
778
|
+
const rotationAngle = handler.getRotation(angle + Math.PI);
|
|
779
|
+
const transformed = localPts.map(
|
|
780
|
+
(p) => rotateAndTranslatePoint(p, rotationAngle, calloutLine[0])
|
|
781
|
+
);
|
|
782
|
+
linePoints.push(...transformed);
|
|
783
|
+
}
|
|
784
|
+
}
|
|
785
|
+
const lineBbox = expandRect(rectFromPoints(linePoints), strokeWidth);
|
|
786
|
+
const tbRight = textBox.origin.x + textBox.size.width;
|
|
787
|
+
const tbBottom = textBox.origin.y + textBox.size.height;
|
|
788
|
+
const lnRight = lineBbox.origin.x + lineBbox.size.width;
|
|
789
|
+
const lnBottom = lineBbox.origin.y + lineBbox.size.height;
|
|
790
|
+
const minX = Math.min(textBox.origin.x, lineBbox.origin.x);
|
|
791
|
+
const minY = Math.min(textBox.origin.y, lineBbox.origin.y);
|
|
792
|
+
const maxX = Math.max(tbRight, lnRight);
|
|
793
|
+
const maxY = Math.max(tbBottom, lnBottom);
|
|
794
|
+
return {
|
|
795
|
+
origin: { x: minX, y: minY },
|
|
796
|
+
size: { width: maxX - minX, height: maxY - minY }
|
|
797
|
+
};
|
|
798
|
+
}
|
|
799
|
+
const calloutVertexConfig = {
|
|
800
|
+
extractVertices: (a) => {
|
|
801
|
+
const textBox = computeTextBoxFromRD(a.rect, a.rectangleDifferences);
|
|
802
|
+
const cl = a.calloutLine;
|
|
803
|
+
if (!cl || cl.length < 3) {
|
|
804
|
+
return [
|
|
805
|
+
{ x: a.rect.origin.x, y: a.rect.origin.y },
|
|
806
|
+
{ x: a.rect.origin.x, y: a.rect.origin.y },
|
|
807
|
+
{ x: textBox.origin.x, y: textBox.origin.y },
|
|
808
|
+
{ x: textBox.origin.x + textBox.size.width, y: textBox.origin.y + textBox.size.height }
|
|
809
|
+
];
|
|
810
|
+
}
|
|
811
|
+
return [
|
|
812
|
+
cl[0],
|
|
813
|
+
cl[1],
|
|
814
|
+
{ x: textBox.origin.x, y: textBox.origin.y },
|
|
815
|
+
{ x: textBox.origin.x + textBox.size.width, y: textBox.origin.y + textBox.size.height }
|
|
816
|
+
];
|
|
817
|
+
},
|
|
818
|
+
transformAnnotation: (a, vertices) => {
|
|
819
|
+
if (vertices.length < 4) return {};
|
|
820
|
+
const [arrowTip, knee, tbTL, tbBR] = vertices;
|
|
821
|
+
const textBox = {
|
|
822
|
+
origin: { x: Math.min(tbTL.x, tbBR.x), y: Math.min(tbTL.y, tbBR.y) },
|
|
823
|
+
size: {
|
|
824
|
+
width: Math.abs(tbBR.x - tbTL.x),
|
|
825
|
+
height: Math.abs(tbBR.y - tbTL.y)
|
|
826
|
+
}
|
|
827
|
+
};
|
|
828
|
+
const connectionPoint = computeCalloutConnectionPoint(knee, textBox);
|
|
829
|
+
const calloutLine = [arrowTip, knee, connectionPoint];
|
|
830
|
+
const overallRect = computeCalloutOverallRect(
|
|
831
|
+
textBox,
|
|
832
|
+
calloutLine,
|
|
833
|
+
a.lineEnding,
|
|
834
|
+
a.strokeWidth ?? 1
|
|
835
|
+
);
|
|
836
|
+
return {
|
|
837
|
+
calloutLine,
|
|
838
|
+
rect: overallRect,
|
|
839
|
+
rectangleDifferences: computeRDFromTextBox(overallRect, textBox)
|
|
840
|
+
};
|
|
841
|
+
}
|
|
842
|
+
};
|
|
740
843
|
function createEnding(ending, strokeWidth, rad, px, py) {
|
|
741
844
|
if (!ending) return null;
|
|
742
845
|
const handler = LINE_ENDING_HANDLERS[ending];
|
|
@@ -1874,6 +1977,80 @@ const patchFreeText = (orig, ctx) => {
|
|
|
1874
1977
|
return ctx.changes;
|
|
1875
1978
|
}
|
|
1876
1979
|
};
|
|
1980
|
+
function rebuildFromVertices(orig, arrowTip, knee, tbTL, tbBR) {
|
|
1981
|
+
const textBox = {
|
|
1982
|
+
origin: { x: Math.min(tbTL.x, tbBR.x), y: Math.min(tbTL.y, tbBR.y) },
|
|
1983
|
+
size: {
|
|
1984
|
+
width: Math.abs(tbBR.x - tbTL.x),
|
|
1985
|
+
height: Math.abs(tbBR.y - tbTL.y)
|
|
1986
|
+
}
|
|
1987
|
+
};
|
|
1988
|
+
const connectionPoint = computeCalloutConnectionPoint(knee, textBox);
|
|
1989
|
+
const calloutLine = [arrowTip, knee, connectionPoint];
|
|
1990
|
+
const overallRect = computeCalloutOverallRect(
|
|
1991
|
+
textBox,
|
|
1992
|
+
calloutLine,
|
|
1993
|
+
orig.lineEnding,
|
|
1994
|
+
orig.strokeWidth ?? 1
|
|
1995
|
+
);
|
|
1996
|
+
return {
|
|
1997
|
+
calloutLine,
|
|
1998
|
+
rect: overallRect,
|
|
1999
|
+
rectangleDifferences: computeRDFromTextBox(overallRect, textBox)
|
|
2000
|
+
};
|
|
2001
|
+
}
|
|
2002
|
+
const patchCalloutFreeText = (orig, ctx) => {
|
|
2003
|
+
var _a, _b;
|
|
2004
|
+
switch (ctx.type) {
|
|
2005
|
+
case "vertex-edit": {
|
|
2006
|
+
if (!ctx.changes.calloutLine) return ctx.changes;
|
|
2007
|
+
const verts = ctx.changes.calloutLine;
|
|
2008
|
+
if (verts.length < 4) return ctx.changes;
|
|
2009
|
+
return rebuildFromVertices(orig, verts[0], verts[1], verts[2], verts[3]);
|
|
2010
|
+
}
|
|
2011
|
+
case "move": {
|
|
2012
|
+
if (!ctx.changes.rect) return ctx.changes;
|
|
2013
|
+
const { dx, dy, rects } = baseMoveChanges(orig, ctx.changes.rect);
|
|
2014
|
+
const movedLine = (_a = orig.calloutLine) == null ? void 0 : _a.map((p) => ({ x: p.x + dx, y: p.y + dy }));
|
|
2015
|
+
return {
|
|
2016
|
+
...rects,
|
|
2017
|
+
...movedLine && { calloutLine: movedLine }
|
|
2018
|
+
};
|
|
2019
|
+
}
|
|
2020
|
+
case "rotate": {
|
|
2021
|
+
const result = baseRotateChanges(orig, ctx);
|
|
2022
|
+
if (!result) return ctx.changes;
|
|
2023
|
+
const { dx, dy } = rotateOrbitDelta(orig, result);
|
|
2024
|
+
const movedLine = (_b = orig.calloutLine) == null ? void 0 : _b.map((p) => ({ x: p.x + dx, y: p.y + dy }));
|
|
2025
|
+
return {
|
|
2026
|
+
...result,
|
|
2027
|
+
...movedLine && { calloutLine: movedLine }
|
|
2028
|
+
};
|
|
2029
|
+
}
|
|
2030
|
+
case "property-update": {
|
|
2031
|
+
if (ctx.changes.lineEnding !== void 0 || ctx.changes.strokeWidth !== void 0) {
|
|
2032
|
+
const merged = { ...orig, ...ctx.changes };
|
|
2033
|
+
if (merged.calloutLine && merged.calloutLine.length >= 3) {
|
|
2034
|
+
const textBox = computeTextBoxFromRD(orig.rect, orig.rectangleDifferences);
|
|
2035
|
+
const overallRect = computeCalloutOverallRect(
|
|
2036
|
+
textBox,
|
|
2037
|
+
merged.calloutLine,
|
|
2038
|
+
merged.lineEnding,
|
|
2039
|
+
merged.strokeWidth ?? 1
|
|
2040
|
+
);
|
|
2041
|
+
return {
|
|
2042
|
+
...ctx.changes,
|
|
2043
|
+
rect: overallRect,
|
|
2044
|
+
rectangleDifferences: computeRDFromTextBox(overallRect, textBox)
|
|
2045
|
+
};
|
|
2046
|
+
}
|
|
2047
|
+
}
|
|
2048
|
+
return ctx.changes;
|
|
2049
|
+
}
|
|
2050
|
+
default:
|
|
2051
|
+
return ctx.changes;
|
|
2052
|
+
}
|
|
2053
|
+
};
|
|
1877
2054
|
const patchStamp = (orig, ctx) => {
|
|
1878
2055
|
switch (ctx.type) {
|
|
1879
2056
|
case "move":
|
|
@@ -1901,11 +2078,17 @@ const index = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.definePropert
|
|
|
1901
2078
|
calculateAABBFromVertices,
|
|
1902
2079
|
calculateRotatedRectAABB,
|
|
1903
2080
|
calculateRotatedRectAABBAroundPoint,
|
|
2081
|
+
calloutVertexConfig,
|
|
1904
2082
|
clampAnnotationToPage,
|
|
1905
2083
|
compensateRotatedVertexEdit,
|
|
2084
|
+
computeCalloutConnectionPoint,
|
|
2085
|
+
computeCalloutOverallRect,
|
|
2086
|
+
computeRDFromTextBox,
|
|
2087
|
+
computeTextBoxFromRD,
|
|
1906
2088
|
createEnding,
|
|
1907
2089
|
getRectCenter,
|
|
1908
2090
|
lineRectWithEndings,
|
|
2091
|
+
patchCalloutFreeText,
|
|
1909
2092
|
patchCircle,
|
|
1910
2093
|
patchFreeText,
|
|
1911
2094
|
patchInk,
|
|
@@ -2138,6 +2321,232 @@ const freeTextHandlerFactory = {
|
|
|
2138
2321
|
};
|
|
2139
2322
|
}
|
|
2140
2323
|
};
|
|
2324
|
+
const CLICK_THRESHOLD = 5;
|
|
2325
|
+
const DEFAULT_TB_WIDTH = 150;
|
|
2326
|
+
const DEFAULT_TB_HEIGHT = 40;
|
|
2327
|
+
const calloutFreeTextHandlerFactory = {
|
|
2328
|
+
annotationType: PdfAnnotationSubtype.FREETEXT,
|
|
2329
|
+
create(context) {
|
|
2330
|
+
const { onCommit, onPreview, getTool, pageSize, pageIndex } = context;
|
|
2331
|
+
const [getPhase, setPhase] = useState("arrow");
|
|
2332
|
+
const [getArrowTip, setArrowTip] = useState(null);
|
|
2333
|
+
const [getKnee, setKnee] = useState(null);
|
|
2334
|
+
const [getDownPos, setDownPos] = useState(null);
|
|
2335
|
+
const [getTextBoxStart, setTextBoxStart] = useState(null);
|
|
2336
|
+
const [getDragging, setDragging] = useState(false);
|
|
2337
|
+
const clampToPage = (pos) => ({
|
|
2338
|
+
x: clamp(pos.x, 0, pageSize.width),
|
|
2339
|
+
y: clamp(pos.y, 0, pageSize.height)
|
|
2340
|
+
});
|
|
2341
|
+
const clampTextBox = (tb) => ({
|
|
2342
|
+
origin: {
|
|
2343
|
+
x: clamp(tb.origin.x, 0, pageSize.width - tb.size.width),
|
|
2344
|
+
y: clamp(tb.origin.y, 0, pageSize.height - tb.size.height)
|
|
2345
|
+
},
|
|
2346
|
+
size: tb.size
|
|
2347
|
+
});
|
|
2348
|
+
const getDefaults = () => {
|
|
2349
|
+
const tool = getTool();
|
|
2350
|
+
if (!tool) return null;
|
|
2351
|
+
return {
|
|
2352
|
+
...tool.defaults,
|
|
2353
|
+
fontColor: tool.defaults.fontColor ?? "#000000",
|
|
2354
|
+
opacity: tool.defaults.opacity ?? 1,
|
|
2355
|
+
fontSize: tool.defaults.fontSize ?? 12,
|
|
2356
|
+
fontFamily: tool.defaults.fontFamily ?? PdfStandardFont.Helvetica,
|
|
2357
|
+
color: tool.defaults.color ?? tool.defaults.backgroundColor ?? "transparent",
|
|
2358
|
+
textAlign: tool.defaults.textAlign ?? PdfTextAlignment.Left,
|
|
2359
|
+
verticalAlign: tool.defaults.verticalAlign ?? PdfVerticalAlignment.Top,
|
|
2360
|
+
contents: tool.defaults.contents ?? "Insert text",
|
|
2361
|
+
flags: tool.defaults.flags ?? ["print"],
|
|
2362
|
+
lineEnding: tool.defaults.lineEnding ?? PdfAnnotationLineEnding.OpenArrow,
|
|
2363
|
+
strokeColor: tool.defaults.strokeColor ?? "#000000",
|
|
2364
|
+
strokeWidth: tool.defaults.strokeWidth ?? 1
|
|
2365
|
+
};
|
|
2366
|
+
};
|
|
2367
|
+
const isClick = (a, b) => Math.abs(a.x - b.x) < CLICK_THRESHOLD && Math.abs(a.y - b.y) < CLICK_THRESHOLD;
|
|
2368
|
+
const buildPreview = (cursor) => {
|
|
2369
|
+
const defaults = getDefaults();
|
|
2370
|
+
if (!defaults) return null;
|
|
2371
|
+
const arrowTip = getArrowTip();
|
|
2372
|
+
const knee = getKnee();
|
|
2373
|
+
const phase = getPhase();
|
|
2374
|
+
if (phase === "knee" && arrowTip) {
|
|
2375
|
+
const calloutLine = [arrowTip, cursor];
|
|
2376
|
+
const minX = Math.min(arrowTip.x, cursor.x);
|
|
2377
|
+
const minY = Math.min(arrowTip.y, cursor.y);
|
|
2378
|
+
const w = Math.abs(arrowTip.x - cursor.x);
|
|
2379
|
+
const h = Math.abs(arrowTip.y - cursor.y);
|
|
2380
|
+
const bounds = {
|
|
2381
|
+
origin: { x: minX, y: minY },
|
|
2382
|
+
size: { width: Math.max(w, 1), height: Math.max(h, 1) }
|
|
2383
|
+
};
|
|
2384
|
+
return {
|
|
2385
|
+
type: PdfAnnotationSubtype.FREETEXT,
|
|
2386
|
+
bounds,
|
|
2387
|
+
data: {
|
|
2388
|
+
...defaults,
|
|
2389
|
+
rect: bounds,
|
|
2390
|
+
calloutLine
|
|
2391
|
+
}
|
|
2392
|
+
};
|
|
2393
|
+
}
|
|
2394
|
+
if (phase === "textbox" && arrowTip && knee) {
|
|
2395
|
+
const tbStart = getTextBoxStart();
|
|
2396
|
+
let textBox;
|
|
2397
|
+
if (getDragging() && tbStart) {
|
|
2398
|
+
textBox = {
|
|
2399
|
+
origin: { x: Math.min(tbStart.x, cursor.x), y: Math.min(tbStart.y, cursor.y) },
|
|
2400
|
+
size: {
|
|
2401
|
+
width: Math.max(Math.abs(cursor.x - tbStart.x), 20),
|
|
2402
|
+
height: Math.max(Math.abs(cursor.y - tbStart.y), 14)
|
|
2403
|
+
}
|
|
2404
|
+
};
|
|
2405
|
+
} else {
|
|
2406
|
+
textBox = {
|
|
2407
|
+
origin: { x: cursor.x - DEFAULT_TB_WIDTH / 2, y: cursor.y - DEFAULT_TB_HEIGHT / 2 },
|
|
2408
|
+
size: { width: DEFAULT_TB_WIDTH, height: DEFAULT_TB_HEIGHT }
|
|
2409
|
+
};
|
|
2410
|
+
}
|
|
2411
|
+
textBox = clampTextBox(textBox);
|
|
2412
|
+
const connectionPoint = computeCalloutConnectionPoint(knee, textBox);
|
|
2413
|
+
const calloutLine = [arrowTip, knee, connectionPoint];
|
|
2414
|
+
const overallRect = computeCalloutOverallRect(
|
|
2415
|
+
textBox,
|
|
2416
|
+
calloutLine,
|
|
2417
|
+
defaults.lineEnding,
|
|
2418
|
+
defaults.strokeWidth
|
|
2419
|
+
);
|
|
2420
|
+
return {
|
|
2421
|
+
type: PdfAnnotationSubtype.FREETEXT,
|
|
2422
|
+
bounds: overallRect,
|
|
2423
|
+
data: {
|
|
2424
|
+
...defaults,
|
|
2425
|
+
rect: overallRect,
|
|
2426
|
+
calloutLine,
|
|
2427
|
+
textBox
|
|
2428
|
+
}
|
|
2429
|
+
};
|
|
2430
|
+
}
|
|
2431
|
+
return null;
|
|
2432
|
+
};
|
|
2433
|
+
const commitCallout = (tb) => {
|
|
2434
|
+
const defaults = getDefaults();
|
|
2435
|
+
const arrowTip = getArrowTip();
|
|
2436
|
+
const knee = getKnee();
|
|
2437
|
+
if (!defaults || !arrowTip || !knee) return;
|
|
2438
|
+
const textBox = clampTextBox(tb);
|
|
2439
|
+
const connectionPoint = computeCalloutConnectionPoint(knee, textBox);
|
|
2440
|
+
const calloutLine = [arrowTip, knee, connectionPoint];
|
|
2441
|
+
const overallRect = computeCalloutOverallRect(
|
|
2442
|
+
textBox,
|
|
2443
|
+
calloutLine,
|
|
2444
|
+
defaults.lineEnding,
|
|
2445
|
+
defaults.strokeWidth
|
|
2446
|
+
);
|
|
2447
|
+
const rd = computeRDFromTextBox(overallRect, textBox);
|
|
2448
|
+
const anno = {
|
|
2449
|
+
...defaults,
|
|
2450
|
+
type: PdfAnnotationSubtype.FREETEXT,
|
|
2451
|
+
intent: "FreeTextCallout",
|
|
2452
|
+
rect: overallRect,
|
|
2453
|
+
rectangleDifferences: rd,
|
|
2454
|
+
calloutLine,
|
|
2455
|
+
pageIndex,
|
|
2456
|
+
id: uuidV4(),
|
|
2457
|
+
created: /* @__PURE__ */ new Date()
|
|
2458
|
+
};
|
|
2459
|
+
onCommit(anno);
|
|
2460
|
+
resetState();
|
|
2461
|
+
};
|
|
2462
|
+
const resetState = () => {
|
|
2463
|
+
setPhase("arrow");
|
|
2464
|
+
setArrowTip(null);
|
|
2465
|
+
setKnee(null);
|
|
2466
|
+
setDownPos(null);
|
|
2467
|
+
setTextBoxStart(null);
|
|
2468
|
+
setDragging(false);
|
|
2469
|
+
onPreview(null);
|
|
2470
|
+
};
|
|
2471
|
+
return {
|
|
2472
|
+
onPointerDown: (pos, evt) => {
|
|
2473
|
+
var _a, _b;
|
|
2474
|
+
const clampedPos = clampToPage(pos);
|
|
2475
|
+
const phase = getPhase();
|
|
2476
|
+
if (phase === "arrow" || phase === "knee") {
|
|
2477
|
+
setDownPos(clampedPos);
|
|
2478
|
+
(_a = evt.setPointerCapture) == null ? void 0 : _a.call(evt);
|
|
2479
|
+
} else if (phase === "textbox") {
|
|
2480
|
+
setTextBoxStart(clampedPos);
|
|
2481
|
+
setDragging(true);
|
|
2482
|
+
(_b = evt.setPointerCapture) == null ? void 0 : _b.call(evt);
|
|
2483
|
+
}
|
|
2484
|
+
},
|
|
2485
|
+
onPointerMove: (pos) => {
|
|
2486
|
+
const clampedPos = clampToPage(pos);
|
|
2487
|
+
const phase = getPhase();
|
|
2488
|
+
if (phase === "textbox" && getDragging()) {
|
|
2489
|
+
onPreview(buildPreview(clampedPos));
|
|
2490
|
+
} else if (phase === "knee" || phase === "textbox") {
|
|
2491
|
+
onPreview(buildPreview(clampedPos));
|
|
2492
|
+
}
|
|
2493
|
+
},
|
|
2494
|
+
onPointerUp: (pos, evt) => {
|
|
2495
|
+
var _a, _b, _c, _d;
|
|
2496
|
+
const clampedPos = clampToPage(pos);
|
|
2497
|
+
const phase = getPhase();
|
|
2498
|
+
const downPos = getDownPos();
|
|
2499
|
+
if (phase === "arrow" && downPos && isClick(downPos, clampedPos)) {
|
|
2500
|
+
setArrowTip(clampedPos);
|
|
2501
|
+
setPhase("knee");
|
|
2502
|
+
setDownPos(null);
|
|
2503
|
+
(_a = evt.releasePointerCapture) == null ? void 0 : _a.call(evt);
|
|
2504
|
+
return;
|
|
2505
|
+
}
|
|
2506
|
+
if (phase === "knee" && downPos && isClick(downPos, clampedPos)) {
|
|
2507
|
+
setKnee(clampedPos);
|
|
2508
|
+
setPhase("textbox");
|
|
2509
|
+
setDownPos(null);
|
|
2510
|
+
(_b = evt.releasePointerCapture) == null ? void 0 : _b.call(evt);
|
|
2511
|
+
return;
|
|
2512
|
+
}
|
|
2513
|
+
if (phase === "textbox" && getDragging()) {
|
|
2514
|
+
const tbStart = getTextBoxStart();
|
|
2515
|
+
if (tbStart) {
|
|
2516
|
+
const minX = Math.min(tbStart.x, clampedPos.x);
|
|
2517
|
+
const minY = Math.min(tbStart.y, clampedPos.y);
|
|
2518
|
+
const w = Math.abs(clampedPos.x - tbStart.x);
|
|
2519
|
+
const h = Math.abs(clampedPos.y - tbStart.y);
|
|
2520
|
+
if (w > 5 || h > 5) {
|
|
2521
|
+
const textBox = {
|
|
2522
|
+
origin: { x: minX, y: minY },
|
|
2523
|
+
size: { width: Math.max(w, 20), height: Math.max(h, 14) }
|
|
2524
|
+
};
|
|
2525
|
+
commitCallout(textBox);
|
|
2526
|
+
} else {
|
|
2527
|
+
commitCallout({
|
|
2528
|
+
origin: {
|
|
2529
|
+
x: tbStart.x - DEFAULT_TB_WIDTH / 2,
|
|
2530
|
+
y: tbStart.y - DEFAULT_TB_HEIGHT / 2
|
|
2531
|
+
},
|
|
2532
|
+
size: { width: DEFAULT_TB_WIDTH, height: DEFAULT_TB_HEIGHT }
|
|
2533
|
+
});
|
|
2534
|
+
}
|
|
2535
|
+
}
|
|
2536
|
+
(_c = evt.releasePointerCapture) == null ? void 0 : _c.call(evt);
|
|
2537
|
+
return;
|
|
2538
|
+
}
|
|
2539
|
+
setDownPos(null);
|
|
2540
|
+
(_d = evt.releasePointerCapture) == null ? void 0 : _d.call(evt);
|
|
2541
|
+
},
|
|
2542
|
+
onPointerCancel: (_, evt) => {
|
|
2543
|
+
var _a;
|
|
2544
|
+
resetState();
|
|
2545
|
+
(_a = evt.releasePointerCapture) == null ? void 0 : _a.call(evt);
|
|
2546
|
+
}
|
|
2547
|
+
};
|
|
2548
|
+
}
|
|
2549
|
+
};
|
|
2141
2550
|
const lineHandlerFactory = {
|
|
2142
2551
|
annotationType: PdfAnnotationSubtype.LINE,
|
|
2143
2552
|
create(context) {
|
|
@@ -3665,7 +4074,7 @@ const freeTextTools = [
|
|
|
3665
4074
|
name: "Free Text",
|
|
3666
4075
|
labelKey: "annotation.freeText",
|
|
3667
4076
|
categories: ["annotation", "markup"],
|
|
3668
|
-
matchScore: (a) => a.type === PdfAnnotationSubtype.FREETEXT ? 1 : 0,
|
|
4077
|
+
matchScore: (a) => a.type === PdfAnnotationSubtype.FREETEXT && a.intent !== "FreeTextCallout" ? 1 : 0,
|
|
3669
4078
|
interaction: {
|
|
3670
4079
|
exclusive: false,
|
|
3671
4080
|
cursor: "crosshair",
|
|
@@ -3705,6 +4114,44 @@ const freeTextTools = [
|
|
|
3705
4114
|
pointerHandler: freeTextHandlerFactory
|
|
3706
4115
|
}
|
|
3707
4116
|
];
|
|
4117
|
+
const calloutFreeTextTools = [
|
|
4118
|
+
{
|
|
4119
|
+
id: "freeTextCallout",
|
|
4120
|
+
name: "Callout",
|
|
4121
|
+
labelKey: "annotation.callout",
|
|
4122
|
+
categories: ["annotation", "markup"],
|
|
4123
|
+
matchScore: (a) => a.type === PdfAnnotationSubtype.FREETEXT && a.intent === "FreeTextCallout" ? 10 : 0,
|
|
4124
|
+
interaction: {
|
|
4125
|
+
exclusive: false,
|
|
4126
|
+
cursor: "crosshair",
|
|
4127
|
+
isDraggable: true,
|
|
4128
|
+
isResizable: false,
|
|
4129
|
+
isRotatable: false
|
|
4130
|
+
},
|
|
4131
|
+
defaults: {
|
|
4132
|
+
type: PdfAnnotationSubtype.FREETEXT,
|
|
4133
|
+
intent: "FreeTextCallout",
|
|
4134
|
+
contents: "Insert text",
|
|
4135
|
+
fontSize: 14,
|
|
4136
|
+
fontColor: "#E44234",
|
|
4137
|
+
fontFamily: PdfStandardFont.Helvetica,
|
|
4138
|
+
textAlign: PdfTextAlignment.Left,
|
|
4139
|
+
verticalAlign: PdfVerticalAlignment.Top,
|
|
4140
|
+
color: "transparent",
|
|
4141
|
+
opacity: 1,
|
|
4142
|
+
lineEnding: PdfAnnotationLineEnding.OpenArrow,
|
|
4143
|
+
strokeColor: "#E44234",
|
|
4144
|
+
strokeWidth: 1
|
|
4145
|
+
},
|
|
4146
|
+
behavior: {
|
|
4147
|
+
insertUpright: true,
|
|
4148
|
+
editAfterCreate: true,
|
|
4149
|
+
selectAfterCreate: true
|
|
4150
|
+
},
|
|
4151
|
+
transform: patchCalloutFreeText,
|
|
4152
|
+
pointerHandler: calloutFreeTextHandlerFactory
|
|
4153
|
+
}
|
|
4154
|
+
];
|
|
3708
4155
|
const stampTools = [
|
|
3709
4156
|
{
|
|
3710
4157
|
id: "stamp",
|
|
@@ -3771,6 +4218,7 @@ const defaultTools = [
|
|
|
3771
4218
|
...polygonTools,
|
|
3772
4219
|
...textCommentTools,
|
|
3773
4220
|
...freeTextTools,
|
|
4221
|
+
...calloutFreeTextTools,
|
|
3774
4222
|
...stampTools,
|
|
3775
4223
|
...linkTools
|
|
3776
4224
|
];
|