@embedpdf/plugin-annotation 1.1.1 → 1.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (107) hide show
  1. package/dist/index.cjs +1 -1
  2. package/dist/index.cjs.map +1 -1
  3. package/dist/index.js +1924 -396
  4. package/dist/index.js.map +1 -1
  5. package/dist/lib/actions.d.ts +21 -15
  6. package/dist/lib/annotation-plugin.d.ts +30 -7
  7. package/dist/lib/handlers/circle.handler.d.ts +3 -0
  8. package/dist/lib/handlers/click-detector.d.ts +27 -0
  9. package/dist/lib/handlers/free-text.handler.d.ts +3 -0
  10. package/dist/lib/handlers/index.d.ts +8 -0
  11. package/dist/lib/handlers/ink.handler.d.ts +3 -0
  12. package/dist/lib/handlers/line.handler.d.ts +3 -0
  13. package/dist/lib/handlers/polygon.handler.d.ts +3 -0
  14. package/dist/lib/handlers/polyline.handler.d.ts +3 -0
  15. package/dist/lib/handlers/square.handler.d.ts +3 -0
  16. package/dist/lib/handlers/stamp.handler.d.ts +3 -0
  17. package/dist/lib/handlers/types.d.ts +139 -0
  18. package/dist/lib/helpers.d.ts +1 -6
  19. package/dist/lib/index.d.ts +3 -1
  20. package/dist/lib/patching/index.d.ts +1 -1
  21. package/dist/lib/patching/patch-registry.d.ts +27 -0
  22. package/dist/lib/patching/patches/index.d.ts +4 -0
  23. package/dist/lib/patching/patches/ink.patch.d.ts +3 -0
  24. package/dist/lib/patching/patches/line.patch.d.ts +3 -0
  25. package/dist/lib/patching/patches/polygon.patch.d.ts +3 -0
  26. package/dist/lib/patching/patches/polyline.patch.d.ts +3 -0
  27. package/dist/lib/selectors.d.ts +8 -12
  28. package/dist/lib/tools/default-tools.d.ts +436 -0
  29. package/dist/lib/tools/tools-utils.d.ts +25 -0
  30. package/dist/lib/tools/types.d.ts +96 -0
  31. package/dist/lib/types.d.ts +78 -161
  32. package/dist/lib/utils/index.d.ts +1 -0
  33. package/dist/lib/utils/use-state.d.ts +12 -0
  34. package/dist/preact/adapter.d.ts +1 -5
  35. package/dist/preact/index.cjs +1 -1
  36. package/dist/preact/index.cjs.map +1 -1
  37. package/dist/preact/index.js +392 -1796
  38. package/dist/preact/index.js.map +1 -1
  39. package/dist/react/adapter.d.ts +2 -4
  40. package/dist/react/index.cjs +1 -1
  41. package/dist/react/index.cjs.map +1 -1
  42. package/dist/react/index.js +393 -1795
  43. package/dist/react/index.js.map +1 -1
  44. package/dist/shared-preact/components/annotation-container.d.ts +18 -16
  45. package/dist/shared-preact/components/annotation-layer.d.ts +9 -2
  46. package/dist/shared-preact/components/annotation-paint-layer.d.ts +6 -0
  47. package/dist/shared-preact/components/annotations/free-text.d.ts +1 -0
  48. package/dist/shared-preact/components/annotations/polygon.d.ts +4 -1
  49. package/dist/shared-preact/components/annotations.d.ts +4 -1
  50. package/dist/shared-preact/components/preview-renderer.d.ts +7 -0
  51. package/dist/shared-preact/components/text-markup/highlight.d.ts +2 -2
  52. package/dist/shared-preact/components/text-markup/squiggly.d.ts +2 -2
  53. package/dist/shared-preact/components/text-markup/strikeout.d.ts +2 -2
  54. package/dist/shared-preact/components/text-markup/underline.d.ts +2 -2
  55. package/dist/shared-preact/types.d.ts +32 -2
  56. package/dist/shared-react/components/annotation-container.d.ts +18 -16
  57. package/dist/shared-react/components/annotation-layer.d.ts +9 -2
  58. package/dist/shared-react/components/annotation-paint-layer.d.ts +6 -0
  59. package/dist/shared-react/components/annotations/free-text.d.ts +1 -0
  60. package/dist/shared-react/components/annotations/polygon.d.ts +4 -1
  61. package/dist/shared-react/components/annotations.d.ts +4 -1
  62. package/dist/shared-react/components/preview-renderer.d.ts +7 -0
  63. package/dist/shared-react/components/text-markup/highlight.d.ts +2 -2
  64. package/dist/shared-react/components/text-markup/squiggly.d.ts +2 -2
  65. package/dist/shared-react/components/text-markup/strikeout.d.ts +2 -2
  66. package/dist/shared-react/components/text-markup/underline.d.ts +2 -2
  67. package/dist/shared-react/types.d.ts +32 -2
  68. package/dist/vue/hooks/index.d.ts +1 -0
  69. package/dist/vue/hooks/use-annotation.d.ts +3 -0
  70. package/dist/vue/index.cjs +2 -0
  71. package/dist/vue/index.cjs.map +1 -0
  72. package/dist/vue/index.d.ts +2 -0
  73. package/dist/vue/index.js +10 -0
  74. package/dist/vue/index.js.map +1 -0
  75. package/package.json +19 -12
  76. package/dist/lib/patching/derived-rect.d.ts +0 -2
  77. package/dist/lib/variant-key.d.ts +0 -8
  78. package/dist/shared-preact/components/annotations/circle-paint.d.ts +0 -10
  79. package/dist/shared-preact/components/annotations/free-text-paint.d.ts +0 -10
  80. package/dist/shared-preact/components/annotations/ink-highlight-paint.d.ts +0 -0
  81. package/dist/shared-preact/components/annotations/ink-paint.d.ts +0 -18
  82. package/dist/shared-preact/components/annotations/line-paint.d.ts +0 -10
  83. package/dist/shared-preact/components/annotations/polygon-paint.d.ts +0 -9
  84. package/dist/shared-preact/components/annotations/polyline-paint.d.ts +0 -10
  85. package/dist/shared-preact/components/annotations/square-paint.d.ts +0 -10
  86. package/dist/shared-preact/components/annotations/stamp-paint.d.ts +0 -8
  87. package/dist/shared-preact/components/resize-handles.d.ts +0 -9
  88. package/dist/shared-preact/components/vertex-editor.d.ts +0 -19
  89. package/dist/shared-preact/hooks/use-drag-resize.d.ts +0 -38
  90. package/dist/shared-preact/patch-ink.d.ts +0 -16
  91. package/dist/shared-preact/patchers.d.ts +0 -9
  92. package/dist/shared-preact/vertex-patchers.d.ts +0 -10
  93. package/dist/shared-react/components/annotations/circle-paint.d.ts +0 -10
  94. package/dist/shared-react/components/annotations/free-text-paint.d.ts +0 -10
  95. package/dist/shared-react/components/annotations/ink-highlight-paint.d.ts +0 -0
  96. package/dist/shared-react/components/annotations/ink-paint.d.ts +0 -17
  97. package/dist/shared-react/components/annotations/line-paint.d.ts +0 -10
  98. package/dist/shared-react/components/annotations/polygon-paint.d.ts +0 -9
  99. package/dist/shared-react/components/annotations/polyline-paint.d.ts +0 -10
  100. package/dist/shared-react/components/annotations/square-paint.d.ts +0 -10
  101. package/dist/shared-react/components/annotations/stamp-paint.d.ts +0 -8
  102. package/dist/shared-react/components/resize-handles.d.ts +0 -9
  103. package/dist/shared-react/components/vertex-editor.d.ts +0 -19
  104. package/dist/shared-react/hooks/use-drag-resize.d.ts +0 -38
  105. package/dist/shared-react/patch-ink.d.ts +0 -16
  106. package/dist/shared-react/patchers.d.ts +0 -9
  107. package/dist/shared-react/vertex-patchers.d.ts +0 -10
@@ -1,325 +1,16 @@
1
1
  import { usePlugin, useCapability } from "@embedpdf/core/preact";
2
2
  import { AnnotationPlugin, patching, getAnnotationsByPageIndex, getSelectedAnnotationByPageIndex, isInk, isSquare, isCircle, isUnderline, isStrikeout, isSquiggly, isHighlight, isLine, isPolyline, isPolygon, isFreeText, isStamp } from "@embedpdf/plugin-annotation";
3
3
  export * from "@embedpdf/plugin-annotation";
4
- import { jsx, jsxs, Fragment as Fragment$1 } from "preact/jsx-runtime";
5
- import { restoreOffset, rectEquals, PdfAnnotationBorderStyle, PdfAnnotationSubtype, expandRect, rectFromPoints, textAlignmentToCss, standardFontCss, PdfVerticalAlignment, ignore, PdfErrorCode, blendModeToCss, PdfBlendMode, uuidV4 } from "@embedpdf/models";
4
+ import { jsxs, jsx, Fragment } from "preact/jsx-runtime";
5
+ import { PdfAnnotationBorderStyle, textAlignmentToCss, standardFontCss, PdfVerticalAlignment, ignore, PdfErrorCode, blendModeToCss, PdfBlendMode, PdfAnnotationSubtype } from "@embedpdf/models";
6
6
  import { usePointerHandlers } from "@embedpdf/plugin-interaction-manager/preact";
7
7
  import { useSelectionCapability } from "@embedpdf/plugin-selection/preact";
8
- import { Fragment } from "preact";
9
- import { useState, useRef, useEffect, useLayoutEffect, useMemo, useCallback } from "preact/hooks";
10
- import { CounterRotate } from "@embedpdf/utils/preact";
11
- import { clamp } from "@embedpdf/core";
8
+ import { Fragment as Fragment$1 } from "preact";
9
+ import { useState, useRef, useEffect, useMemo, useLayoutEffect, useCallback } from "preact/hooks";
10
+ import { useInteractionHandles, useDoublePressProps, CounterRotate } from "@embedpdf/utils/preact";
12
11
  const useAnnotationPlugin = () => usePlugin(AnnotationPlugin.id);
13
12
  const useAnnotationCapability = () => useCapability(AnnotationPlugin.id);
14
- const mapDoubleClick = (handler) => handler ? { onDblClick: handler } : {};
15
- function VertexEditor({
16
- rect,
17
- rotation,
18
- scale,
19
- vertices,
20
- onEdit,
21
- onCommit,
22
- handleSize = 12
23
- }) {
24
- const [dragIdx, setDragIdx] = useState(null);
25
- const startScreen = useRef(null);
26
- const startVerts = useRef([]);
27
- const applyDelta = (deltaScreen) => {
28
- const deltaPdf = restoreOffset(deltaScreen, rotation, scale);
29
- const next = [...startVerts.current];
30
- if (dragIdx !== null) {
31
- next[dragIdx] = {
32
- x: next[dragIdx].x + deltaPdf.x,
33
- y: next[dragIdx].y + deltaPdf.y
34
- };
35
- }
36
- return next;
37
- };
38
- const handleDown = (idx) => (e) => {
39
- e.stopPropagation();
40
- e.preventDefault();
41
- setDragIdx(idx);
42
- startScreen.current = { x: e.clientX, y: e.clientY };
43
- startVerts.current = vertices;
44
- e.target.setPointerCapture(e.pointerId);
45
- };
46
- const handleMove = (e) => {
47
- if (dragIdx === null || !startScreen.current) return;
48
- const deltaRaw = {
49
- x: e.clientX - startScreen.current.x,
50
- y: e.clientY - startScreen.current.y
51
- };
52
- onEdit(applyDelta(deltaRaw));
53
- };
54
- const handleUp = (e) => {
55
- if (dragIdx === null || !startScreen.current) return;
56
- e.target.releasePointerCapture(e.pointerId);
57
- const deltaRaw = {
58
- x: e.clientX - startScreen.current.x,
59
- y: e.clientY - startScreen.current.y
60
- };
61
- onCommit(applyDelta(deltaRaw));
62
- setDragIdx(null);
63
- };
64
- return /* @__PURE__ */ jsx(Fragment, { children: vertices.map((v, i) => {
65
- const left = (v.x - rect.origin.x) * scale - handleSize / 2;
66
- const top = (v.y - rect.origin.y) * scale - handleSize / 2;
67
- return /* @__PURE__ */ jsx(
68
- "div",
69
- {
70
- style: {
71
- position: "absolute",
72
- left,
73
- top,
74
- width: handleSize,
75
- height: handleSize,
76
- borderRadius: "50%",
77
- background: "#2196f3",
78
- cursor: "pointer",
79
- pointerEvents: "auto",
80
- zIndex: 4
81
- },
82
- onPointerDown: handleDown(i),
83
- onPointerMove: handleMove,
84
- onPointerUp: handleUp
85
- },
86
- i
87
- );
88
- }) });
89
- }
90
- function useDragResize({
91
- scale,
92
- pageWidth,
93
- pageHeight,
94
- rotation,
95
- tracked,
96
- isSelected,
97
- isDraggable,
98
- isResizable,
99
- computePatch,
100
- computeVertices,
101
- lockAspectRatio = false,
102
- currentRect,
103
- setCurrentRect,
104
- setCurrentVertices,
105
- setPreviewObject,
106
- commit
107
- }) {
108
- const drag = useRef("idle");
109
- const dir = useRef("none");
110
- const startPos = useRef(null);
111
- const startRect = useRef(null);
112
- const clamp2 = (v, min, max) => Math.max(min, Math.min(max, v));
113
- const pageW = pageWidth / scale;
114
- const pageH = pageHeight / scale;
115
- const applyDelta = (dx, dy) => {
116
- if (!startRect.current) return currentRect;
117
- let { origin, size } = startRect.current;
118
- let ox = origin.x;
119
- let oy = origin.y;
120
- let w = size.width;
121
- let h = size.height;
122
- if (drag.current === "dragging") {
123
- ox += dx;
124
- oy += dy;
125
- } else if (drag.current === "resizing") {
126
- if (dir.current.includes("right")) w += dx;
127
- else if (dir.current.includes("left")) {
128
- ox += dx;
129
- w -= dx;
130
- }
131
- if (dir.current.includes("bottom")) h += dy;
132
- else if (dir.current.includes("top")) {
133
- oy += dy;
134
- h -= dy;
135
- }
136
- if (lockAspectRatio && startRect.current) {
137
- const ratio = startRect.current.size.width / startRect.current.size.height;
138
- const anchorRight = ox + w;
139
- const anchorBottom = oy + h;
140
- const horizontalPrimary = dir.current.includes("left") || dir.current.includes("right");
141
- if (horizontalPrimary) {
142
- h = w / ratio;
143
- } else {
144
- w = h * ratio;
145
- }
146
- if (dir.current.includes("left")) {
147
- ox = anchorRight - w;
148
- }
149
- if (dir.current.includes("top")) {
150
- oy = anchorBottom - h;
151
- }
152
- }
153
- }
154
- if (w < 1 || h < 1) return currentRect;
155
- w = clamp2(w, 1, pageW);
156
- h = clamp2(h, 1, pageH);
157
- ox = clamp2(ox, 0, pageW - w);
158
- oy = clamp2(oy, 0, pageH - h);
159
- return { origin: { x: ox, y: oy }, size: { width: w, height: h } };
160
- };
161
- const beginDrag = (kind, clientX, clientY) => {
162
- drag.current = kind;
163
- startPos.current = { x: clientX, y: clientY };
164
- startRect.current = currentRect;
165
- };
166
- const handleMove = (clientX, clientY) => {
167
- if (drag.current === "idle" || !startPos.current) return;
168
- const disp = {
169
- x: clientX - startPos.current.x,
170
- y: clientY - startPos.current.y
171
- };
172
- const { x, y } = restoreOffset(disp, rotation, scale);
173
- const nextRect = applyDelta(x, y);
174
- let patch = { rect: nextRect };
175
- if (computePatch) {
176
- patch = computePatch(tracked.object, {
177
- rect: nextRect,
178
- direction: drag.current === "resizing" ? dir.current : "bottom-right"
179
- });
180
- if (computeVertices) setCurrentVertices(computeVertices({ ...tracked.object, ...patch }));
181
- }
182
- setCurrentRect(patch.rect ?? nextRect);
183
- setPreviewObject(patch);
184
- };
185
- const finishDragInternal = () => {
186
- if (drag.current === "idle") return;
187
- const usedDir = dir.current || "bottom-right";
188
- drag.current = "idle";
189
- let patch = { rect: currentRect };
190
- if (computePatch) {
191
- patch = computePatch(tracked.object, {
192
- rect: currentRect,
193
- direction: usedDir
194
- });
195
- }
196
- commit(patch);
197
- startPos.current = null;
198
- startRect.current = null;
199
- dir.current = "none";
200
- setPreviewObject(null);
201
- };
202
- const onPointerDown = (e) => {
203
- if (!isSelected || !isDraggable) return;
204
- e.stopPropagation();
205
- e.preventDefault();
206
- beginDrag("dragging", e.clientX, e.clientY);
207
- e.currentTarget.setPointerCapture(e.pointerId);
208
- };
209
- const onPointerMove = (e) => handleMove(e.clientX, e.clientY);
210
- const onPointerUp = (e) => {
211
- finishDragInternal();
212
- if ((e == null ? void 0 : e.currentTarget) && e.pointerId !== void 0) {
213
- try {
214
- e.currentTarget.releasePointerCapture(e.pointerId);
215
- } catch {
216
- }
217
- }
218
- };
219
- const startResize = (direction) => (e) => {
220
- if (!isSelected || !isResizable) return;
221
- e.stopPropagation();
222
- e.preventDefault();
223
- dir.current = direction;
224
- beginDrag("resizing", e.clientX, e.clientY);
225
- e.currentTarget.setPointerCapture(e.pointerId);
226
- };
227
- const onTouchStart = (e) => {
228
- if (!isSelected || !isDraggable) return;
229
- e.stopPropagation();
230
- e.preventDefault();
231
- const t = e.touches[0];
232
- if (!t) return;
233
- beginDrag("dragging", t.clientX, t.clientY);
234
- };
235
- const onTouchMove = (e) => {
236
- const t = e.touches[0];
237
- if (!t) return;
238
- handleMove(t.clientX, t.clientY);
239
- };
240
- const onTouchEnd = () => finishDragInternal();
241
- useEffect(() => {
242
- drag.current = "idle";
243
- dir.current = "none";
244
- startPos.current = null;
245
- startRect.current = null;
246
- }, [tracked]);
247
- return {
248
- rootHandlers: {
249
- onPointerDown,
250
- onPointerMove,
251
- onPointerUp,
252
- onPointerCancel: () => onPointerUp(),
253
- onLostPointerCapture: () => onPointerUp(),
254
- /* mobile touch fallback */
255
- onTouchStart,
256
- onTouchMove,
257
- onTouchEnd,
258
- onTouchCancel: onTouchEnd
259
- },
260
- startResize
261
- };
262
- }
263
- const commonStyle = (o) => ({
264
- position: "absolute",
265
- width: 13,
266
- height: 13,
267
- background: "blue",
268
- borderRadius: "50%"
269
- });
270
- function ResizeHandles({ rotation, outlineOffset = 1, startResize }) {
271
- const o = outlineOffset;
272
- return /* @__PURE__ */ jsxs(Fragment$1, { children: [
273
- /* @__PURE__ */ jsx(
274
- "div",
275
- {
276
- style: {
277
- ...commonStyle(),
278
- top: -7 - o,
279
- left: -7 - o,
280
- cursor: rotation % 2 ? "nesw-resize" : "nwse-resize"
281
- },
282
- onPointerDown: startResize("top-left")
283
- }
284
- ),
285
- /* @__PURE__ */ jsx(
286
- "div",
287
- {
288
- style: {
289
- ...commonStyle(),
290
- top: -7 - o,
291
- right: -7 - o,
292
- cursor: rotation % 2 ? "nwse-resize" : "nesw-resize"
293
- },
294
- onPointerDown: startResize("top-right")
295
- }
296
- ),
297
- /* @__PURE__ */ jsx(
298
- "div",
299
- {
300
- style: {
301
- ...commonStyle(),
302
- bottom: -7 - o,
303
- left: -7 - o,
304
- cursor: rotation % 2 ? "nwse-resize" : "nesw-resize"
305
- },
306
- onPointerDown: startResize("bottom-left")
307
- }
308
- ),
309
- /* @__PURE__ */ jsx(
310
- "div",
311
- {
312
- style: {
313
- ...commonStyle(),
314
- bottom: -7 - o,
315
- right: -7 - o,
316
- cursor: rotation % 2 ? "nesw-resize" : "nwse-resize"
317
- },
318
- onPointerDown: startResize("bottom-right")
319
- }
320
- )
321
- ] });
322
- }
13
+ const suppressContentEditableWarningProps = {};
323
14
  function AnnotationContainer({
324
15
  scale,
325
16
  pageIndex,
@@ -328,111 +19,135 @@ function AnnotationContainer({
328
19
  pageHeight,
329
20
  trackedAnnotation,
330
21
  children,
331
- style,
332
- outlineOffset = 1,
333
- isSelected = false,
334
- isDraggable = true,
335
- isResizable = true,
22
+ isSelected,
23
+ isDraggable,
24
+ isResizable,
336
25
  lockAspectRatio = false,
337
- computeVertices,
338
- computePatch,
26
+ style = {},
27
+ vertexConfig,
339
28
  selectionMenu,
29
+ outlineOffset = 1,
340
30
  onDoubleClick,
31
+ zIndex = 1,
32
+ resizeUI,
33
+ vertexUI,
34
+ selectionOutlineColor = "#007ACC",
341
35
  ...props
342
36
  }) {
37
+ const [preview, setPreview] = useState(trackedAnnotation.object);
343
38
  const { provides: annotationProvides } = useAnnotationCapability();
344
- const [currentRect, setCurrentRect] = useState(trackedAnnotation.object.rect);
345
- const [currentVertices, setCurrentVertices] = useState(
346
- (computeVertices == null ? void 0 : computeVertices(trackedAnnotation.object)) ?? []
347
- );
348
- const [previewObject, setPreviewObject] = useState(null);
349
- const { rootHandlers, startResize } = useDragResize({
350
- scale,
351
- pageWidth,
352
- pageHeight,
353
- rotation,
354
- tracked: trackedAnnotation,
355
- isSelected,
356
- isDraggable,
357
- isResizable,
358
- lockAspectRatio,
359
- computePatch,
360
- computeVertices,
361
- currentRect,
362
- setCurrentRect,
363
- setCurrentVertices,
364
- setPreviewObject,
365
- commit: (patch) => annotationProvides == null ? void 0 : annotationProvides.updateAnnotation(pageIndex, trackedAnnotation.object.id, patch)
39
+ const gestureBaseRef = useRef(null);
40
+ const currentObject = preview ? { ...trackedAnnotation.object, ...preview } : trackedAnnotation.object;
41
+ const HANDLE_COLOR = (resizeUI == null ? void 0 : resizeUI.color) ?? "#007ACC";
42
+ const VERTEX_COLOR = (vertexUI == null ? void 0 : vertexUI.color) ?? "#007ACC";
43
+ const HANDLE_SIZE = (resizeUI == null ? void 0 : resizeUI.size) ?? 12;
44
+ const VERTEX_SIZE = (vertexUI == null ? void 0 : vertexUI.size) ?? 12;
45
+ const { dragProps, vertices, resize } = useInteractionHandles({
46
+ controller: {
47
+ element: currentObject.rect,
48
+ vertices: vertexConfig == null ? void 0 : vertexConfig.extractVertices(currentObject),
49
+ constraints: {
50
+ minWidth: 10,
51
+ minHeight: 10,
52
+ boundingBox: { width: pageWidth / scale, height: pageHeight / scale }
53
+ },
54
+ maintainAspectRatio: lockAspectRatio,
55
+ pageRotation: rotation,
56
+ scale,
57
+ enabled: isSelected,
58
+ onUpdate: (event) => {
59
+ var _a;
60
+ if (!((_a = event.transformData) == null ? void 0 : _a.type)) return;
61
+ if (event.state === "start") {
62
+ gestureBaseRef.current = currentObject;
63
+ }
64
+ const transformType = event.transformData.type;
65
+ const base = gestureBaseRef.current ?? currentObject;
66
+ const changes = event.transformData.changes.vertices ? vertexConfig == null ? void 0 : vertexConfig.transformAnnotation(base, event.transformData.changes.vertices) : { rect: event.transformData.changes.rect };
67
+ const patched = annotationProvides == null ? void 0 : annotationProvides.transformAnnotation(base, {
68
+ type: transformType,
69
+ changes,
70
+ metadata: event.transformData.metadata
71
+ });
72
+ if (patched) {
73
+ setPreview((prev) => ({
74
+ ...prev,
75
+ ...patched
76
+ }));
77
+ }
78
+ if (event.state === "end" && patched) {
79
+ gestureBaseRef.current = null;
80
+ annotationProvides == null ? void 0 : annotationProvides.updateAnnotation(pageIndex, trackedAnnotation.object.id, patched);
81
+ }
82
+ }
83
+ },
84
+ resizeUI: {
85
+ handleSize: HANDLE_SIZE,
86
+ spacing: outlineOffset,
87
+ offsetMode: "outside",
88
+ includeSides: lockAspectRatio ? false : true,
89
+ zIndex: zIndex + 1
90
+ },
91
+ vertexUI: {
92
+ vertexSize: VERTEX_SIZE,
93
+ zIndex: zIndex + 2
94
+ },
95
+ includeVertices: vertexConfig ? true : false
366
96
  });
367
- useLayoutEffect(() => {
368
- if (!rectEquals(trackedAnnotation.object.rect, currentRect)) {
369
- setCurrentRect(trackedAnnotation.object.rect);
370
- setPreviewObject((prev) => prev ? { ...prev, rect: trackedAnnotation.object.rect } : null);
371
- setCurrentVertices((computeVertices == null ? void 0 : computeVertices(trackedAnnotation.object)) ?? []);
372
- }
373
- }, [trackedAnnotation]);
374
- const currentObject = previewObject ? { ...trackedAnnotation.object, ...previewObject } : trackedAnnotation.object;
375
- return /* @__PURE__ */ jsxs(Fragment, { children: [
97
+ const doubleProps = useDoublePressProps(onDoubleClick);
98
+ useEffect(() => {
99
+ setPreview(trackedAnnotation.object);
100
+ }, [trackedAnnotation.object]);
101
+ return /* @__PURE__ */ jsxs("div", { "data-no-interaction": true, children: [
376
102
  /* @__PURE__ */ jsxs(
377
103
  "div",
378
104
  {
379
- ...rootHandlers,
380
- ...mapDoubleClick(onDoubleClick),
105
+ ...isDraggable && isSelected ? dragProps : {},
106
+ ...doubleProps,
381
107
  style: {
382
108
  position: "absolute",
383
- outline: isSelected ? "1px solid #007ACC" : "none",
109
+ left: currentObject.rect.origin.x * scale,
110
+ top: currentObject.rect.origin.y * scale,
111
+ width: currentObject.rect.size.width * scale,
112
+ height: currentObject.rect.size.height * scale,
113
+ outline: isSelected ? `1px solid ${selectionOutlineColor}` : "none",
384
114
  outlineOffset: isSelected ? `${outlineOffset}px` : "0px",
385
- left: `${currentRect.origin.x * scale}px`,
386
- top: `${currentRect.origin.y * scale}px`,
387
- width: `${currentRect.size.width * scale}px`,
388
- height: `${currentRect.size.height * scale}px`,
389
115
  pointerEvents: isSelected ? "auto" : "none",
390
- touchAction: isSelected ? "auto" : "none",
116
+ touchAction: "none",
391
117
  cursor: isSelected && isDraggable ? "move" : "default",
392
- ...isSelected && {
393
- zIndex: 3
394
- },
118
+ zIndex,
395
119
  ...style
396
120
  },
397
121
  ...props,
398
122
  children: [
399
123
  typeof children === "function" ? children(currentObject) : children,
400
- isSelected && currentVertices.length > 0 && /* @__PURE__ */ jsx(
401
- VertexEditor,
402
- {
403
- rect: currentRect,
404
- rotation,
405
- scale,
406
- vertices: currentVertices,
407
- onEdit: (v) => {
408
- setCurrentVertices(v);
409
- if (computePatch) {
410
- const patch = computePatch(trackedAnnotation.object, {
411
- rect: currentRect,
412
- vertices: v
413
- });
414
- setPreviewObject(patch);
415
- setCurrentRect(patch.rect || currentRect);
416
- }
124
+ isSelected && isResizable && resize.map(
125
+ ({ key, ...hProps }) => (resizeUI == null ? void 0 : resizeUI.component) ? resizeUI.component({
126
+ key,
127
+ ...hProps,
128
+ backgroundColor: HANDLE_COLOR
129
+ }) : /* @__PURE__ */ jsx(
130
+ "div",
131
+ {
132
+ ...hProps,
133
+ style: { ...hProps.style, backgroundColor: HANDLE_COLOR }
417
134
  },
418
- onCommit: (v) => {
419
- if (annotationProvides && computePatch) {
420
- const patch = computePatch(trackedAnnotation.object, {
421
- rect: currentRect,
422
- vertices: v
423
- });
424
- annotationProvides.updateAnnotation(pageIndex, trackedAnnotation.object.id, patch);
425
- }
426
- }
427
- }
135
+ key
136
+ )
428
137
  ),
429
- isSelected && isResizable && /* @__PURE__ */ jsx(
430
- ResizeHandles,
431
- {
432
- rotation,
433
- outlineOffset,
434
- startResize
435
- }
138
+ isSelected && vertices.map(
139
+ ({ key, ...vProps }) => (vertexUI == null ? void 0 : vertexUI.component) ? vertexUI.component({
140
+ key,
141
+ ...vProps,
142
+ backgroundColor: VERTEX_COLOR
143
+ }) : /* @__PURE__ */ jsx(
144
+ "div",
145
+ {
146
+ ...vProps,
147
+ style: { ...vProps.style, backgroundColor: VERTEX_COLOR }
148
+ },
149
+ key
150
+ )
436
151
  )
437
152
  ]
438
153
  }
@@ -441,8 +156,14 @@ function AnnotationContainer({
441
156
  CounterRotate,
442
157
  {
443
158
  rect: {
444
- origin: { x: currentRect.origin.x * scale, y: currentRect.origin.y * scale },
445
- size: { width: currentRect.size.width * scale, height: currentRect.size.height * scale }
159
+ origin: {
160
+ x: currentObject.rect.origin.x * scale,
161
+ y: currentObject.rect.origin.y * scale
162
+ },
163
+ size: {
164
+ width: currentObject.rect.size.width * scale,
165
+ height: currentObject.rect.size.height * scale
166
+ }
446
167
  },
447
168
  rotation,
448
169
  children: ({ rect, menuWrapperProps }) => selectionMenu && selectionMenu({
@@ -458,14 +179,14 @@ function AnnotationContainer({
458
179
  function Highlight({
459
180
  color = "#FFFF00",
460
181
  opacity = 0.5,
461
- rects,
182
+ segmentRects,
462
183
  rect,
463
184
  scale,
464
185
  onClick,
465
186
  style,
466
187
  ...props
467
188
  }) {
468
- return /* @__PURE__ */ jsx(Fragment$1, { children: rects.map((b, i) => /* @__PURE__ */ jsx(
189
+ return /* @__PURE__ */ jsx(Fragment, { children: segmentRects.map((b, i) => /* @__PURE__ */ jsx(
469
190
  "div",
470
191
  {
471
192
  onPointerDown: onClick,
@@ -491,7 +212,7 @@ function Highlight({
491
212
  function Underline({
492
213
  color = "#FFFF00",
493
214
  opacity = 0.5,
494
- rects,
215
+ segmentRects,
495
216
  rect,
496
217
  scale,
497
218
  onClick,
@@ -499,7 +220,7 @@ function Underline({
499
220
  ...props
500
221
  }) {
501
222
  const thickness = 2 * scale;
502
- return /* @__PURE__ */ jsx(Fragment$1, { children: rects.map((r, i) => /* @__PURE__ */ jsx(
223
+ return /* @__PURE__ */ jsx(Fragment, { children: segmentRects.map((r, i) => /* @__PURE__ */ jsx(
503
224
  "div",
504
225
  {
505
226
  onPointerDown: onClick,
@@ -539,7 +260,7 @@ function Underline({
539
260
  function Strikeout({
540
261
  color = "#FFFF00",
541
262
  opacity = 0.5,
542
- rects,
263
+ segmentRects,
543
264
  rect,
544
265
  scale,
545
266
  onClick,
@@ -547,7 +268,7 @@ function Strikeout({
547
268
  ...props
548
269
  }) {
549
270
  const thickness = 2 * scale;
550
- return /* @__PURE__ */ jsx(Fragment$1, { children: rects.map((r, i) => /* @__PURE__ */ jsx(
271
+ return /* @__PURE__ */ jsx(Fragment, { children: segmentRects.map((r, i) => /* @__PURE__ */ jsx(
551
272
  "div",
552
273
  {
553
274
  onPointerDown: onClick,
@@ -588,7 +309,7 @@ function Strikeout({
588
309
  function Squiggly({
589
310
  color = "#FFFF00",
590
311
  opacity = 0.5,
591
- rects,
312
+ segmentRects,
592
313
  rect,
593
314
  scale,
594
315
  onClick,
@@ -602,7 +323,7 @@ function Squiggly({
602
323
  fill="none" stroke="${color}" stroke-width="${amplitude}" stroke-linecap="round"/>
603
324
  </svg>`;
604
325
  const svgDataUri = `url("data:image/svg+xml;utf8,${encodeURIComponent(svg)}")`;
605
- return /* @__PURE__ */ jsx(Fragment$1, { children: rects.map((r, i) => /* @__PURE__ */ jsx(
326
+ return /* @__PURE__ */ jsx(Fragment, { children: segmentRects.map((r, i) => /* @__PURE__ */ jsx(
606
327
  "div",
607
328
  {
608
329
  onPointerDown: onClick,
@@ -831,48 +552,6 @@ function Circle({
831
552
  }
832
553
  );
833
554
  }
834
- const patchInk = (original, ctx) => {
835
- if (original.type !== PdfAnnotationSubtype.INK) {
836
- throw new Error("resizeInkAnnotation: original is not an ink annotation");
837
- }
838
- const oldRect = original.rect;
839
- let scaleX = ctx.rect.size.width / oldRect.size.width;
840
- let scaleY = ctx.rect.size.height / oldRect.size.height;
841
- const minSize = 10;
842
- if (ctx.rect.size.width < minSize || ctx.rect.size.height < minSize) {
843
- scaleX = Math.max(scaleX, minSize / oldRect.size.width);
844
- scaleY = Math.max(scaleY, minSize / oldRect.size.height);
845
- ctx.rect = {
846
- origin: ctx.rect.origin,
847
- size: {
848
- width: oldRect.size.width * scaleX,
849
- height: oldRect.size.height * scaleY
850
- }
851
- };
852
- }
853
- if (ctx.uniform) {
854
- const minScale = Math.min(scaleX, scaleY);
855
- scaleX = minScale;
856
- scaleY = minScale;
857
- ctx.rect.size = {
858
- width: oldRect.size.width * minScale,
859
- height: oldRect.size.height * minScale
860
- };
861
- }
862
- const newInkList = original.inkList.map((stroke) => ({
863
- points: stroke.points.map((p) => ({
864
- x: ctx.rect.origin.x + (p.x - oldRect.origin.x) * scaleX,
865
- y: ctx.rect.origin.y + (p.y - oldRect.origin.y) * scaleY
866
- }))
867
- }));
868
- const avgScale = (scaleX + scaleY) / 2;
869
- const newStrokeWidth = Math.round(original.strokeWidth * avgScale);
870
- return {
871
- rect: ctx.rect,
872
- inkList: newInkList,
873
- strokeWidth: newStrokeWidth
874
- };
875
- };
876
555
  function Line({
877
556
  color = "transparent",
878
557
  opacity = 1,
@@ -1009,13 +688,13 @@ function Polyline({
1009
688
  const endings = useMemo(() => {
1010
689
  if (localPts.length < 2) return { start: null, end: null };
1011
690
  const toAngle = (a, b) => Math.atan2(b.y - a.y, b.x - a.x);
1012
- const startRad = toAngle(localPts[1], localPts[0]);
691
+ const startRad = toAngle(localPts[0], localPts[1]);
1013
692
  const endRad = toAngle(localPts[localPts.length - 2], localPts[localPts.length - 1]);
1014
693
  const start = patching.createEnding(
1015
694
  lineEndings == null ? void 0 : lineEndings.start,
1016
695
  strokeWidth,
1017
696
  startRad + Math.PI,
1018
- // tip points outward from first segment start
697
+ // tip points outward from line start
1019
698
  localPts[0].x,
1020
699
  localPts[0].y
1021
700
  );
@@ -1023,6 +702,7 @@ function Polyline({
1023
702
  lineEndings == null ? void 0 : lineEndings.end,
1024
703
  strokeWidth,
1025
704
  endRad,
705
+ // tip points in line direction
1026
706
  localPts[localPts.length - 1].x,
1027
707
  localPts[localPts.length - 1].y
1028
708
  );
@@ -1112,20 +792,27 @@ function Polygon({
1112
792
  strokeDashArray,
1113
793
  scale,
1114
794
  isSelected,
1115
- onClick
795
+ onClick,
796
+ currentVertex,
797
+ // A preview-only prop
798
+ handleSize = 14
799
+ // in CSS pixels
1116
800
  }) {
801
+ const allPoints = currentVertex ? [...vertices, currentVertex] : vertices;
1117
802
  const localPts = useMemo(
1118
- () => vertices.map(({ x, y }) => ({ x: x - rect.origin.x, y: y - rect.origin.y })),
1119
- [vertices, rect]
803
+ () => allPoints.map(({ x, y }) => ({ x: x - rect.origin.x, y: y - rect.origin.y })),
804
+ [allPoints, rect]
1120
805
  );
1121
806
  const pathData = useMemo(() => {
1122
807
  if (!localPts.length) return "";
1123
808
  const [first, ...rest] = localPts;
1124
- return (`M ${first.x} ${first.y} ` + rest.map((p) => `L ${p.x} ${p.y} `).join("") + "Z").trim();
1125
- }, [localPts]);
809
+ const isPreview = !!currentVertex;
810
+ return (`M ${first.x} ${first.y} ` + rest.map((p) => `L ${p.x} ${p.y}`).join(" ") + (isPreview ? "" : " Z")).trim();
811
+ }, [localPts, currentVertex]);
812
+ const isPreviewing = currentVertex && vertices.length > 0;
1126
813
  const width = rect.size.width * scale;
1127
814
  const height = rect.size.height * scale;
1128
- return /* @__PURE__ */ jsx(
815
+ return /* @__PURE__ */ jsxs(
1129
816
  "svg",
1130
817
  {
1131
818
  style: {
@@ -1139,79 +826,54 @@ function Polygon({
1139
826
  width,
1140
827
  height,
1141
828
  viewBox: `0 0 ${rect.size.width} ${rect.size.height}`,
1142
- children: /* @__PURE__ */ jsx(
1143
- "path",
1144
- {
1145
- d: pathData,
1146
- onPointerDown: onClick,
1147
- onTouchStart: onClick,
1148
- opacity,
1149
- style: {
1150
- fill: color,
1151
- stroke: strokeColor ?? color,
1152
- strokeWidth,
1153
- cursor: isSelected ? "move" : "pointer",
1154
- pointerEvents: isSelected ? "none" : color === "transparent" ? "visibleStroke" : "visible",
1155
- strokeLinecap: "butt",
1156
- strokeLinejoin: "miter",
1157
- ...strokeStyle === PdfAnnotationBorderStyle.DASHED && {
1158
- strokeDasharray: strokeDashArray == null ? void 0 : strokeDashArray.join(",")
829
+ children: [
830
+ /* @__PURE__ */ jsx(
831
+ "path",
832
+ {
833
+ d: pathData,
834
+ onPointerDown: onClick,
835
+ onTouchStart: onClick,
836
+ opacity,
837
+ style: {
838
+ fill: currentVertex ? "none" : color,
839
+ // No fill during preview
840
+ stroke: strokeColor ?? color,
841
+ strokeWidth,
842
+ cursor: isSelected ? "move" : "pointer",
843
+ pointerEvents: isSelected ? "none" : color === "transparent" ? "visibleStroke" : "visible",
844
+ strokeLinecap: "butt",
845
+ strokeLinejoin: "miter",
846
+ ...strokeStyle === PdfAnnotationBorderStyle.DASHED && {
847
+ strokeDasharray: strokeDashArray == null ? void 0 : strokeDashArray.join(",")
848
+ }
1159
849
  }
1160
850
  }
1161
- }
1162
- )
851
+ ),
852
+ isPreviewing && vertices.length > 1 && /* @__PURE__ */ jsx(
853
+ "path",
854
+ {
855
+ d: `M ${localPts[localPts.length - 1].x} ${localPts[localPts.length - 1].y} L ${localPts[0].x} ${localPts[0].y}`,
856
+ fill: "none",
857
+ style: { stroke: strokeColor, strokeWidth, strokeDasharray: "4,4", opacity: 0.7 }
858
+ }
859
+ ),
860
+ isPreviewing && vertices.length >= 2 && /* @__PURE__ */ jsx(
861
+ "rect",
862
+ {
863
+ x: localPts[0].x - handleSize / scale / 2,
864
+ y: localPts[0].y - handleSize / scale / 2,
865
+ width: handleSize / scale,
866
+ height: handleSize / scale,
867
+ fill: strokeColor,
868
+ opacity: 0.4,
869
+ stroke: strokeColor,
870
+ strokeWidth: strokeWidth / 2
871
+ }
872
+ )
873
+ ]
1163
874
  }
1164
875
  );
1165
876
  }
1166
- const patchLine = (orig, ctx) => {
1167
- if (ctx.vertices && ctx.vertices.length >= 2) {
1168
- const rect = patching.lineRectWithEndings(ctx.vertices, orig.strokeWidth, orig.lineEndings);
1169
- return {
1170
- rect,
1171
- linePoints: { start: ctx.vertices[0], end: ctx.vertices[1] }
1172
- };
1173
- }
1174
- const dx = ctx.rect.origin.x - orig.rect.origin.x;
1175
- const dy = ctx.rect.origin.y - orig.rect.origin.y;
1176
- return {
1177
- rect: ctx.rect,
1178
- linePoints: {
1179
- start: { x: orig.linePoints.start.x + dx, y: orig.linePoints.start.y + dy },
1180
- end: { x: orig.linePoints.end.x + dx, y: orig.linePoints.end.y + dy }
1181
- }
1182
- };
1183
- };
1184
- const patchPolyline = (orig, ctx) => {
1185
- if (ctx.vertices && ctx.vertices.length) {
1186
- return {
1187
- rect: patching.lineRectWithEndings(ctx.vertices, orig.strokeWidth, orig.lineEndings),
1188
- vertices: ctx.vertices
1189
- };
1190
- }
1191
- const dx = ctx.rect.origin.x - orig.rect.origin.x;
1192
- const dy = ctx.rect.origin.y - orig.rect.origin.y;
1193
- const moved = orig.vertices.map((p) => ({ x: p.x + dx, y: p.y + dy }));
1194
- return {
1195
- rect: ctx.rect,
1196
- vertices: moved
1197
- };
1198
- };
1199
- const patchPolygon = (orig, ctx) => {
1200
- if (ctx.vertices && ctx.vertices.length) {
1201
- const pad = orig.strokeWidth / 2;
1202
- return {
1203
- rect: expandRect(rectFromPoints(ctx.vertices), pad),
1204
- vertices: ctx.vertices
1205
- };
1206
- }
1207
- const dx = ctx.rect.origin.x - orig.rect.origin.x;
1208
- const dy = ctx.rect.origin.y - orig.rect.origin.y;
1209
- const moved = orig.vertices.map((p) => ({ x: p.x + dx, y: p.y + dy }));
1210
- return {
1211
- rect: ctx.rect,
1212
- vertices: moved
1213
- };
1214
- };
1215
877
  function FreeText({
1216
878
  isSelected,
1217
879
  isEditing,
@@ -1222,6 +884,7 @@ function FreeText({
1222
884
  }) {
1223
885
  const editorRef = useRef(null);
1224
886
  const { provides: annotationProvides } = useAnnotationCapability();
887
+ const [isIOS, setIsIOS] = useState(false);
1225
888
  useEffect(() => {
1226
889
  if (isEditing && editorRef.current) {
1227
890
  const editor = editorRef.current;
@@ -1236,6 +899,15 @@ function FreeText({
1236
899
  }
1237
900
  }
1238
901
  }, [isEditing]);
902
+ useLayoutEffect(() => {
903
+ try {
904
+ const nav = navigator;
905
+ const ios = /iPad|iPhone|iPod/.test(navigator.userAgent) || navigator.platform === "MacIntel" && (nav == null ? void 0 : nav.maxTouchPoints) > 1;
906
+ setIsIOS(ios);
907
+ } catch {
908
+ setIsIOS(false);
909
+ }
910
+ }, []);
1239
911
  const handleBlur = () => {
1240
912
  if (!annotationProvides) return;
1241
913
  if (!editorRef.current) return;
@@ -1243,6 +915,12 @@ function FreeText({
1243
915
  contents: editorRef.current.innerText
1244
916
  });
1245
917
  };
918
+ const computedFontPx = annotation.object.fontSize * scale;
919
+ const MIN_IOS_FOCUS_FONT_PX = 16;
920
+ const needsComp = isIOS && isEditing && computedFontPx > 0 && computedFontPx < MIN_IOS_FOCUS_FONT_PX;
921
+ const adjustedFontPx = needsComp ? MIN_IOS_FOCUS_FONT_PX : computedFontPx;
922
+ const scaleComp = needsComp ? computedFontPx / MIN_IOS_FOCUS_FONT_PX : 1;
923
+ const invScalePercent = needsComp ? 100 / scaleComp : 100;
1246
924
  return /* @__PURE__ */ jsx(
1247
925
  "div",
1248
926
  {
@@ -1261,9 +939,10 @@ function FreeText({
1261
939
  {
1262
940
  ref: editorRef,
1263
941
  onBlur: handleBlur,
942
+ tabIndex: 0,
1264
943
  style: {
1265
944
  color: annotation.object.fontColor,
1266
- fontSize: annotation.object.fontSize * scale,
945
+ fontSize: adjustedFontPx,
1267
946
  fontFamily: standardFontCss(annotation.object.fontFamily),
1268
947
  textAlign: textAlignmentToCss(annotation.object.textAlign),
1269
948
  flexDirection: "column",
@@ -1271,13 +950,17 @@ function FreeText({
1271
950
  display: "flex",
1272
951
  backgroundColor: annotation.object.backgroundColor,
1273
952
  opacity: annotation.object.opacity,
1274
- width: "100%",
1275
- height: "100%",
953
+ width: needsComp ? `${invScalePercent}%` : "100%",
954
+ height: needsComp ? `${invScalePercent}%` : "100%",
1276
955
  lineHeight: "1.18",
1277
956
  overflow: "hidden",
1278
- cursor: isEditing ? "text" : "pointer"
957
+ cursor: isEditing ? "text" : "pointer",
958
+ outline: "none",
959
+ transform: needsComp ? `scale(${scaleComp})` : void 0,
960
+ transformOrigin: "top left"
1279
961
  },
1280
962
  contentEditable: isEditing,
963
+ ...suppressContentEditableWarningProps,
1281
964
  children: annotation.object.contents
1282
965
  }
1283
966
  )
@@ -1329,7 +1012,7 @@ function RenderAnnotation({
1329
1012
  urlRef.current = null;
1330
1013
  }
1331
1014
  };
1332
- return /* @__PURE__ */ jsx(Fragment, { children: imageUrl && /* @__PURE__ */ jsx(
1015
+ return /* @__PURE__ */ jsx(Fragment$1, { children: imageUrl && /* @__PURE__ */ jsx(
1333
1016
  "img",
1334
1017
  {
1335
1018
  src: imageUrl,
@@ -1352,7 +1035,8 @@ function Stamp({ isSelected, annotation, pageIndex, scale, onClick }) {
1352
1035
  width: "100%",
1353
1036
  height: "100%",
1354
1037
  zIndex: 2,
1355
- pointerEvents: isSelected ? "none" : "auto"
1038
+ pointerEvents: isSelected ? "none" : "auto",
1039
+ cursor: "pointer"
1356
1040
  },
1357
1041
  onPointerDown: onClick,
1358
1042
  onTouchStart: onClick,
@@ -1400,15 +1084,17 @@ function Annotations(annotationsProps) {
1400
1084
  if (annotationProvides && selectionProvides) {
1401
1085
  annotationProvides.selectAnnotation(pageIndex, annotation.object.id);
1402
1086
  selectionProvides.clear();
1403
- setEditingId(null);
1087
+ if (annotation.object.id !== editingId) {
1088
+ setEditingId(null);
1089
+ }
1404
1090
  }
1405
1091
  },
1406
- [annotationProvides, selectionProvides, pageIndex]
1092
+ [annotationProvides, selectionProvides, editingId, pageIndex]
1407
1093
  );
1408
1094
  useEffect(() => {
1409
1095
  return register(handlers);
1410
1096
  }, [register, handlers]);
1411
- return /* @__PURE__ */ jsx(Fragment$1, { children: annotations.map((annotation) => {
1097
+ return /* @__PURE__ */ jsx(Fragment, { children: annotations.map((annotation) => {
1412
1098
  const isSelected = (selectionState == null ? void 0 : selectionState.object.id) === annotation.object.id;
1413
1099
  const isEditing = editingId === annotation.object.id;
1414
1100
  if (isInk(annotation)) {
@@ -1420,7 +1106,6 @@ function Annotations(annotationsProps) {
1420
1106
  isDraggable: true,
1421
1107
  isResizable: true,
1422
1108
  selectionMenu,
1423
- computePatch: patchInk,
1424
1109
  style: {
1425
1110
  mixBlendMode: blendModeToCss(annotation.object.blendMode ?? PdfBlendMode.Normal)
1426
1111
  },
@@ -1428,12 +1113,8 @@ function Annotations(annotationsProps) {
1428
1113
  children: (obj) => /* @__PURE__ */ jsx(
1429
1114
  Ink,
1430
1115
  {
1116
+ ...obj,
1431
1117
  isSelected,
1432
- color: obj.color,
1433
- opacity: obj.opacity,
1434
- strokeWidth: obj.strokeWidth,
1435
- inkList: obj.inkList,
1436
- rect: obj.rect,
1437
1118
  scale,
1438
1119
  onClick: (e) => handleClick(e, annotation)
1439
1120
  }
@@ -1458,14 +1139,8 @@ function Annotations(annotationsProps) {
1458
1139
  children: (obj) => /* @__PURE__ */ jsx(
1459
1140
  Square,
1460
1141
  {
1142
+ ...obj,
1461
1143
  isSelected,
1462
- rect: obj.rect,
1463
- color: obj.color,
1464
- opacity: obj.opacity,
1465
- strokeWidth: obj.strokeWidth,
1466
- strokeColor: obj.strokeColor,
1467
- strokeStyle: obj.strokeStyle,
1468
- strokeDashArray: obj.strokeDashArray,
1469
1144
  scale,
1470
1145
  onClick: (e) => handleClick(e, annotation)
1471
1146
  }
@@ -1490,14 +1165,8 @@ function Annotations(annotationsProps) {
1490
1165
  children: (obj) => /* @__PURE__ */ jsx(
1491
1166
  Circle,
1492
1167
  {
1168
+ ...obj,
1493
1169
  isSelected,
1494
- rect: obj.rect,
1495
- color: obj.color,
1496
- opacity: obj.opacity,
1497
- strokeWidth: obj.strokeWidth,
1498
- strokeColor: obj.strokeColor,
1499
- strokeStyle: obj.strokeStyle,
1500
- strokeDashArray: obj.strokeDashArray,
1501
1170
  scale,
1502
1171
  onClick: (e) => handleClick(e, annotation)
1503
1172
  }
@@ -1515,21 +1184,12 @@ function Annotations(annotationsProps) {
1515
1184
  isDraggable: false,
1516
1185
  isResizable: false,
1517
1186
  selectionMenu,
1187
+ zIndex: 0,
1518
1188
  style: {
1519
1189
  mixBlendMode: blendModeToCss(annotation.object.blendMode ?? PdfBlendMode.Normal)
1520
1190
  },
1521
1191
  ...annotationsProps,
1522
- children: (obj) => /* @__PURE__ */ jsx(
1523
- Underline,
1524
- {
1525
- rect: obj.rect,
1526
- color: obj.color,
1527
- opacity: obj.opacity,
1528
- rects: obj.segmentRects,
1529
- scale,
1530
- onClick: (e) => handleClick(e, annotation)
1531
- }
1532
- )
1192
+ children: (obj) => /* @__PURE__ */ jsx(Underline, { ...obj, scale, onClick: (e) => handleClick(e, annotation) })
1533
1193
  },
1534
1194
  annotation.object.id
1535
1195
  );
@@ -1543,21 +1203,12 @@ function Annotations(annotationsProps) {
1543
1203
  isDraggable: false,
1544
1204
  isResizable: false,
1545
1205
  selectionMenu,
1206
+ zIndex: 0,
1546
1207
  style: {
1547
1208
  mixBlendMode: blendModeToCss(annotation.object.blendMode ?? PdfBlendMode.Normal)
1548
1209
  },
1549
1210
  ...annotationsProps,
1550
- children: (obj) => /* @__PURE__ */ jsx(
1551
- Strikeout,
1552
- {
1553
- rect: obj.rect,
1554
- color: obj.color,
1555
- opacity: obj.opacity,
1556
- rects: obj.segmentRects,
1557
- scale,
1558
- onClick: (e) => handleClick(e, annotation)
1559
- }
1560
- )
1211
+ children: (obj) => /* @__PURE__ */ jsx(Strikeout, { ...obj, scale, onClick: (e) => handleClick(e, annotation) })
1561
1212
  },
1562
1213
  annotation.object.id
1563
1214
  );
@@ -1571,21 +1222,12 @@ function Annotations(annotationsProps) {
1571
1222
  isDraggable: false,
1572
1223
  isResizable: false,
1573
1224
  selectionMenu,
1225
+ zIndex: 0,
1574
1226
  style: {
1575
1227
  mixBlendMode: blendModeToCss(annotation.object.blendMode ?? PdfBlendMode.Normal)
1576
1228
  },
1577
1229
  ...annotationsProps,
1578
- children: (obj) => /* @__PURE__ */ jsx(
1579
- Squiggly,
1580
- {
1581
- color: obj.color,
1582
- opacity: obj.opacity,
1583
- rects: obj.segmentRects,
1584
- rect: obj.rect,
1585
- scale,
1586
- onClick: (e) => handleClick(e, annotation)
1587
- }
1588
- )
1230
+ children: (obj) => /* @__PURE__ */ jsx(Squiggly, { ...obj, scale, onClick: (e) => handleClick(e, annotation) })
1589
1231
  },
1590
1232
  annotation.object.id
1591
1233
  );
@@ -1599,21 +1241,12 @@ function Annotations(annotationsProps) {
1599
1241
  isDraggable: false,
1600
1242
  isResizable: false,
1601
1243
  selectionMenu,
1244
+ zIndex: 0,
1602
1245
  style: {
1603
1246
  mixBlendMode: blendModeToCss(annotation.object.blendMode ?? PdfBlendMode.Multiply)
1604
1247
  },
1605
1248
  ...annotationsProps,
1606
- children: (obj) => /* @__PURE__ */ jsx(
1607
- Highlight,
1608
- {
1609
- color: obj.color,
1610
- opacity: obj.opacity,
1611
- rects: obj.segmentRects,
1612
- scale,
1613
- rect: obj.rect,
1614
- onClick: (e) => handleClick(e, annotation)
1615
- }
1616
- )
1249
+ children: (obj) => /* @__PURE__ */ jsx(Highlight, { ...obj, scale, onClick: (e) => handleClick(e, annotation) })
1617
1250
  },
1618
1251
  annotation.object.id
1619
1252
  );
@@ -1627,28 +1260,30 @@ function Annotations(annotationsProps) {
1627
1260
  isDraggable: true,
1628
1261
  isResizable: false,
1629
1262
  selectionMenu,
1630
- computePatch: patchLine,
1631
- computeVertices: (annotation2) => [
1632
- annotation2.linePoints.start,
1633
- annotation2.linePoints.end
1634
- ],
1263
+ vertexConfig: {
1264
+ extractVertices: (annotation2) => [
1265
+ annotation2.linePoints.start,
1266
+ annotation2.linePoints.end
1267
+ ],
1268
+ transformAnnotation: (annotation2, vertices) => {
1269
+ return {
1270
+ ...annotation2,
1271
+ linePoints: {
1272
+ start: vertices[0],
1273
+ end: vertices[1]
1274
+ }
1275
+ };
1276
+ }
1277
+ },
1635
1278
  style: {
1636
1279
  mixBlendMode: blendModeToCss(annotation.object.blendMode ?? PdfBlendMode.Normal)
1637
1280
  },
1638
1281
  ...annotationsProps,
1639
- children: (obj) => /* @__PURE__ */ jsx(Fragment, { children: /* @__PURE__ */ jsx(
1282
+ children: (obj) => /* @__PURE__ */ jsx(Fragment$1, { children: /* @__PURE__ */ jsx(
1640
1283
  Line,
1641
1284
  {
1285
+ ...obj,
1642
1286
  isSelected,
1643
- rect: obj.rect,
1644
- color: obj.color,
1645
- opacity: obj.opacity,
1646
- linePoints: obj.linePoints,
1647
- lineEndings: obj.lineEndings,
1648
- strokeWidth: obj.strokeWidth,
1649
- strokeColor: obj.strokeColor,
1650
- strokeStyle: obj.strokeStyle,
1651
- strokeDashArray: obj.strokeDashArray,
1652
1287
  scale,
1653
1288
  onClick: (e) => handleClick(e, annotation)
1654
1289
  }
@@ -1666,23 +1301,24 @@ function Annotations(annotationsProps) {
1666
1301
  isDraggable: true,
1667
1302
  isResizable: false,
1668
1303
  selectionMenu,
1669
- computePatch: patchPolyline,
1670
- computeVertices: (annotation2) => annotation2.vertices,
1304
+ vertexConfig: {
1305
+ extractVertices: (annotation2) => annotation2.vertices,
1306
+ transformAnnotation: (annotation2, vertices) => {
1307
+ return {
1308
+ ...annotation2,
1309
+ vertices
1310
+ };
1311
+ }
1312
+ },
1671
1313
  style: {
1672
1314
  mixBlendMode: blendModeToCss(annotation.object.blendMode ?? PdfBlendMode.Normal)
1673
1315
  },
1674
1316
  ...annotationsProps,
1675
- children: (obj) => /* @__PURE__ */ jsx(Fragment, { children: /* @__PURE__ */ jsx(
1317
+ children: (obj) => /* @__PURE__ */ jsx(Fragment$1, { children: /* @__PURE__ */ jsx(
1676
1318
  Polyline,
1677
1319
  {
1320
+ ...obj,
1678
1321
  isSelected,
1679
- rect: obj.rect,
1680
- color: obj.color,
1681
- opacity: obj.opacity,
1682
- vertices: obj.vertices,
1683
- lineEndings: obj.lineEndings,
1684
- strokeWidth: obj.strokeWidth,
1685
- strokeColor: obj.strokeColor,
1686
1322
  scale,
1687
1323
  onClick: (e) => handleClick(e, annotation)
1688
1324
  }
@@ -1700,24 +1336,24 @@ function Annotations(annotationsProps) {
1700
1336
  isDraggable: true,
1701
1337
  isResizable: false,
1702
1338
  selectionMenu,
1703
- computeVertices: (annotation2) => annotation2.vertices,
1704
- computePatch: patchPolygon,
1339
+ vertexConfig: {
1340
+ extractVertices: (annotation2) => annotation2.vertices,
1341
+ transformAnnotation: (annotation2, vertices) => {
1342
+ return {
1343
+ ...annotation2,
1344
+ vertices
1345
+ };
1346
+ }
1347
+ },
1705
1348
  style: {
1706
1349
  mixBlendMode: blendModeToCss(annotation.object.blendMode ?? PdfBlendMode.Normal)
1707
1350
  },
1708
1351
  ...annotationsProps,
1709
- children: (obj) => /* @__PURE__ */ jsx(Fragment, { children: /* @__PURE__ */ jsx(
1352
+ children: (obj) => /* @__PURE__ */ jsx(Fragment$1, { children: /* @__PURE__ */ jsx(
1710
1353
  Polygon,
1711
1354
  {
1355
+ ...obj,
1712
1356
  isSelected,
1713
- rect: obj.rect,
1714
- color: obj.color,
1715
- opacity: obj.opacity,
1716
- vertices: obj.vertices,
1717
- strokeWidth: obj.strokeWidth,
1718
- strokeColor: obj.strokeColor,
1719
- strokeStyle: obj.strokeStyle,
1720
- strokeDashArray: obj.strokeDashArray,
1721
1357
  scale,
1722
1358
  onClick: (e) => handleClick(e, annotation)
1723
1359
  }
@@ -1732,17 +1368,16 @@ function Annotations(annotationsProps) {
1732
1368
  {
1733
1369
  trackedAnnotation: annotation,
1734
1370
  isSelected,
1735
- isDraggable: true,
1371
+ isDraggable: !isEditing,
1736
1372
  isResizable: true,
1737
1373
  selectionMenu,
1738
- outlineOffset: 6,
1374
+ style: {
1375
+ mixBlendMode: blendModeToCss(annotation.object.blendMode ?? PdfBlendMode.Normal)
1376
+ },
1739
1377
  onDoubleClick: (e) => {
1740
1378
  e.stopPropagation();
1741
1379
  setEditingId(annotation.object.id);
1742
1380
  },
1743
- style: {
1744
- mixBlendMode: blendModeToCss(annotation.object.blendMode ?? PdfBlendMode.Normal)
1745
- },
1746
1381
  ...annotationsProps,
1747
1382
  children: (object) => /* @__PURE__ */ jsx(
1748
1383
  FreeText,
@@ -1799,7 +1434,7 @@ function TextMarkup({ pageIndex, scale }) {
1799
1434
  const { provides: annotationProvides } = useAnnotationCapability();
1800
1435
  const [rects, setRects] = useState([]);
1801
1436
  const [boundingRect, setBoundingRect] = useState(null);
1802
- const [activeTool, setActiveTool] = useState({ variantKey: null, defaults: null });
1437
+ const [activeTool, setActiveTool] = useState(null);
1803
1438
  useEffect(() => {
1804
1439
  if (!selectionProvides) return;
1805
1440
  const off = selectionProvides.onSelectionChange(() => {
@@ -1814,8 +1449,8 @@ function TextMarkup({ pageIndex, scale }) {
1814
1449
  return off;
1815
1450
  }, [annotationProvides]);
1816
1451
  if (!boundingRect) return null;
1817
- if (!activeTool.defaults) return null;
1818
- switch (activeTool.defaults.subtype) {
1452
+ if (!activeTool || !activeTool.defaults) return null;
1453
+ switch (activeTool.defaults.type) {
1819
1454
  case PdfAnnotationSubtype.UNDERLINE:
1820
1455
  return /* @__PURE__ */ jsx(
1821
1456
  "div",
@@ -1831,7 +1466,7 @@ function TextMarkup({ pageIndex, scale }) {
1831
1466
  {
1832
1467
  color: (_b = activeTool.defaults) == null ? void 0 : _b.color,
1833
1468
  opacity: (_c = activeTool.defaults) == null ? void 0 : _c.opacity,
1834
- rects,
1469
+ segmentRects: rects,
1835
1470
  scale
1836
1471
  }
1837
1472
  )
@@ -1852,7 +1487,7 @@ function TextMarkup({ pageIndex, scale }) {
1852
1487
  {
1853
1488
  color: (_e = activeTool.defaults) == null ? void 0 : _e.color,
1854
1489
  opacity: (_f = activeTool.defaults) == null ? void 0 : _f.opacity,
1855
- rects,
1490
+ segmentRects: rects,
1856
1491
  scale
1857
1492
  }
1858
1493
  )
@@ -1873,7 +1508,7 @@ function TextMarkup({ pageIndex, scale }) {
1873
1508
  {
1874
1509
  color: (_h = activeTool.defaults) == null ? void 0 : _h.color,
1875
1510
  opacity: (_i = activeTool.defaults) == null ? void 0 : _i.opacity,
1876
- rects,
1511
+ segmentRects: rects,
1877
1512
  scale
1878
1513
  }
1879
1514
  )
@@ -1894,7 +1529,7 @@ function TextMarkup({ pageIndex, scale }) {
1894
1529
  {
1895
1530
  color: (_k = activeTool.defaults) == null ? void 0 : _k.color,
1896
1531
  opacity: (_l = activeTool.defaults) == null ? void 0 : _l.opacity,
1897
- rects,
1532
+ segmentRects: rects,
1898
1533
  scale
1899
1534
  }
1900
1535
  )
@@ -1904,1110 +1539,131 @@ function TextMarkup({ pageIndex, scale }) {
1904
1539
  return null;
1905
1540
  }
1906
1541
  }
1907
- const InkPaint = ({ pageIndex, scale, pageWidth, pageHeight }) => {
1908
- var _a, _b, _c, _d, _e;
1909
- const { provides: annotationProvides } = useAnnotationCapability();
1910
- const [activeTool, setActiveTool] = useState({ variantKey: null, defaults: null });
1911
- useEffect(() => {
1912
- if (!annotationProvides) return;
1913
- const off = annotationProvides.onActiveToolChange(setActiveTool);
1914
- return off;
1915
- }, [annotationProvides]);
1916
- if (!activeTool.defaults) return null;
1917
- if (activeTool.defaults.subtype !== PdfAnnotationSubtype.INK) return null;
1918
- const toolColor = ((_a = activeTool.defaults) == null ? void 0 : _a.color) ?? "#000000";
1919
- const toolOpacity = ((_b = activeTool.defaults) == null ? void 0 : _b.opacity) ?? 1;
1920
- const toolStrokeWidth = ((_c = activeTool.defaults) == null ? void 0 : _c.strokeWidth) ?? 2;
1921
- const toolBlendMode = ((_d = activeTool.defaults) == null ? void 0 : _d.blendMode) ?? PdfBlendMode.Normal;
1922
- const intent = (_e = activeTool.defaults) == null ? void 0 : _e.intent;
1923
- const { register } = usePointerHandlers({ modeId: "ink", pageIndex });
1924
- const [currentStrokes, setCurrentStrokes] = useState([]);
1925
- const [isDrawing, setIsDrawing] = useState(false);
1926
- const timerRef = useRef(null);
1927
- const pageWidthPDF = pageWidth / scale;
1928
- const pageHeightPDF = pageHeight / scale;
1929
- const handlers = useMemo(
1930
- () => ({
1931
- onPointerDown: (pos, evt) => {
1932
- var _a2;
1933
- const curX = clamp(pos.x, 0, pageWidthPDF);
1934
- const curY = clamp(pos.y, 0, pageHeightPDF);
1935
- setIsDrawing(true);
1936
- if (timerRef.current) {
1937
- clearTimeout(timerRef.current);
1938
- timerRef.current = null;
1939
- setCurrentStrokes((prev) => [...prev, { points: [{ x: curX, y: curY }] }]);
1940
- } else {
1941
- setCurrentStrokes([{ points: [{ x: curX, y: curY }] }]);
1942
- }
1943
- (_a2 = evt.setPointerCapture) == null ? void 0 : _a2.call(evt);
1944
- },
1945
- onPointerMove: (pos) => {
1946
- if (!isDrawing) return;
1947
- const curX = clamp(pos.x, 0, pageWidthPDF);
1948
- const curY = clamp(pos.y, 0, pageHeightPDF);
1949
- setCurrentStrokes((prev) => {
1950
- if (!prev.length) return prev;
1951
- const last = prev[prev.length - 1];
1952
- const newLast = { points: [...last.points, { x: curX, y: curY }] };
1953
- return [...prev.slice(0, -1), newLast];
1954
- });
1955
- },
1956
- onPointerUp: (_, evt) => {
1957
- var _a2;
1958
- setIsDrawing(false);
1959
- (_a2 = evt.releasePointerCapture) == null ? void 0 : _a2.call(evt);
1960
- if (timerRef.current) clearTimeout(timerRef.current);
1961
- timerRef.current = setTimeout(() => {
1962
- if (currentStrokes.length && annotationProvides) {
1963
- const allPoints2 = currentStrokes.flatMap((s) => s.points);
1964
- if (!allPoints2.length) return;
1965
- const rect2 = expandRect(rectFromPoints(allPoints2), toolStrokeWidth / 2);
1966
- if (rect2.size.width < 1 || rect2.size.height < 1) return;
1967
- const anno = {
1968
- type: PdfAnnotationSubtype.INK,
1969
- intent,
1970
- blendMode: toolBlendMode,
1971
- rect: rect2,
1972
- inkList: currentStrokes,
1973
- color: toolColor,
1974
- opacity: toolOpacity,
1975
- strokeWidth: toolStrokeWidth,
1976
- created: /* @__PURE__ */ new Date(),
1977
- pageIndex,
1978
- id: uuidV4()
1979
- };
1980
- annotationProvides.createAnnotation(pageIndex, anno);
1981
- annotationProvides.setActiveVariant(null);
1982
- annotationProvides.selectAnnotation(pageIndex, anno.id);
1983
- }
1984
- setCurrentStrokes([]);
1985
- timerRef.current = null;
1986
- }, 3e3);
1987
- },
1988
- onPointerCancel: (_, evt) => {
1989
- var _a2;
1990
- setIsDrawing(false);
1991
- (_a2 = evt.releasePointerCapture) == null ? void 0 : _a2.call(evt);
1992
- setCurrentStrokes([]);
1993
- if (timerRef.current) {
1994
- clearTimeout(timerRef.current);
1995
- timerRef.current = null;
1996
- }
1997
- }
1998
- }),
1999
- [
2000
- pageWidthPDF,
2001
- pageHeightPDF,
2002
- currentStrokes,
2003
- annotationProvides,
2004
- pageIndex,
2005
- toolColor,
2006
- toolOpacity,
2007
- toolStrokeWidth,
2008
- isDrawing
2009
- ]
2010
- );
2011
- useEffect(() => {
2012
- if (!register) return;
2013
- return register(handlers);
2014
- }, [register, handlers]);
2015
- useEffect(() => {
2016
- return () => {
2017
- if (timerRef.current) clearTimeout(timerRef.current);
2018
- };
2019
- }, []);
2020
- if (!currentStrokes.length) return null;
2021
- const allPoints = currentStrokes.flatMap((s) => s.points);
2022
- if (!allPoints.length) return null;
2023
- const rect = expandRect(rectFromPoints(allPoints), toolStrokeWidth / 2);
2024
- const paths = currentStrokes.map(({ points }) => {
2025
- let d = "";
2026
- points.forEach(({ x, y }, i) => {
2027
- const lx = x - rect.origin.x;
2028
- const ly = y - rect.origin.y;
2029
- d += (i === 0 ? "M" : "L") + lx + " " + ly + " ";
2030
- });
2031
- return d.trim();
2032
- });
2033
- return /* @__PURE__ */ jsx(
2034
- "svg",
2035
- {
2036
- style: {
2037
- position: "absolute",
2038
- left: rect.origin.x * scale,
2039
- top: rect.origin.y * scale,
2040
- width: rect.size.width * scale,
2041
- height: rect.size.height * scale,
2042
- pointerEvents: "none",
2043
- zIndex: 2
2044
- },
2045
- width: rect.size.width * scale,
2046
- height: rect.size.height * scale,
2047
- viewBox: `0 0 ${rect.size.width} ${rect.size.height}`,
2048
- children: paths.map((d, i) => /* @__PURE__ */ jsx(
2049
- "path",
2050
- {
2051
- d,
2052
- fill: "none",
2053
- opacity: toolOpacity,
2054
- style: {
2055
- stroke: toolColor,
2056
- strokeWidth: toolStrokeWidth,
2057
- strokeLinecap: "round",
2058
- strokeLinejoin: "round"
2059
- }
2060
- },
2061
- i
2062
- ))
2063
- }
2064
- );
2065
- };
2066
- const CirclePaint = ({
2067
- pageIndex,
2068
- scale,
2069
- pageWidth,
2070
- pageHeight,
2071
- cursor
2072
- }) => {
2073
- const { provides: annotationProvides } = useAnnotationCapability();
2074
- const [activeTool, setActiveTool] = useState({ variantKey: null, defaults: null });
2075
- useEffect(() => {
2076
- if (!annotationProvides) return;
2077
- return annotationProvides.onActiveToolChange(setActiveTool);
2078
- }, [annotationProvides]);
2079
- if (!activeTool.defaults) return null;
2080
- if (activeTool.defaults.subtype !== PdfAnnotationSubtype.CIRCLE) return null;
2081
- const toolColor = activeTool.defaults.color ?? "#000000";
2082
- const toolOpacity = activeTool.defaults.opacity ?? 1;
2083
- const toolStrokeWidth = activeTool.defaults.strokeWidth ?? 2;
2084
- const toolStrokeColor = activeTool.defaults.strokeColor ?? "#000000";
2085
- const toolStrokeStyle = activeTool.defaults.strokeStyle ?? PdfAnnotationBorderStyle.SOLID;
2086
- const toolStrokeDashArray = activeTool.defaults.strokeDashArray ?? [];
2087
- const { register } = usePointerHandlers({ modeId: "circle", pageIndex });
2088
- const pageWidthPDF = pageWidth / scale;
2089
- const pageHeightPDF = pageHeight / scale;
2090
- const [start, setStart] = useState(null);
2091
- const [current, setCurrent] = useState(null);
2092
- const handlers = useMemo(
2093
- () => ({
2094
- onPointerDown: (pos, evt) => {
2095
- var _a;
2096
- const x = clamp(pos.x, 0, pageWidthPDF);
2097
- const y = clamp(pos.y, 0, pageHeightPDF);
2098
- setStart({ x, y });
2099
- setCurrent({ x, y });
2100
- (_a = evt.setPointerCapture) == null ? void 0 : _a.call(evt);
2101
- },
2102
- onPointerMove: (pos) => {
2103
- if (!start) return;
2104
- const x = clamp(pos.x, 0, pageWidthPDF);
2105
- const y = clamp(pos.y, 0, pageHeightPDF);
2106
- setCurrent({ x, y });
2107
- },
2108
- onPointerUp: (_, evt) => {
2109
- var _a;
2110
- if (start && current && annotationProvides) {
2111
- const minX2 = Math.min(start.x, current.x);
2112
- const minY2 = Math.min(start.y, current.y);
2113
- const maxX2 = Math.max(start.x, current.x);
2114
- const maxY2 = Math.max(start.y, current.y);
2115
- if (maxX2 - minX2 >= 1 && maxY2 - minY2 >= 1) {
2116
- const halfStroke2 = toolStrokeWidth / 2;
2117
- const rect = {
2118
- origin: { x: minX2 - halfStroke2, y: minY2 - halfStroke2 },
2119
- size: {
2120
- width: maxX2 - minX2 + toolStrokeWidth,
2121
- height: maxY2 - minY2 + toolStrokeWidth
2122
- }
2123
- };
2124
- const anno = {
2125
- type: PdfAnnotationSubtype.CIRCLE,
2126
- rect,
2127
- flags: ["print"],
2128
- color: toolColor,
2129
- opacity: toolOpacity,
2130
- strokeWidth: toolStrokeWidth,
2131
- strokeColor: toolStrokeColor,
2132
- strokeStyle: toolStrokeStyle,
2133
- strokeDashArray: toolStrokeDashArray,
2134
- created: /* @__PURE__ */ new Date(),
2135
- pageIndex,
2136
- id: uuidV4()
2137
- };
2138
- annotationProvides.createAnnotation(pageIndex, anno);
2139
- annotationProvides.setActiveVariant(null);
2140
- annotationProvides.selectAnnotation(pageIndex, anno.id);
2141
- }
2142
- }
2143
- (_a = evt.releasePointerCapture) == null ? void 0 : _a.call(evt);
2144
- setStart(null);
2145
- setCurrent(null);
2146
- },
2147
- onPointerCancel: (_, evt) => {
2148
- var _a;
2149
- (_a = evt.releasePointerCapture) == null ? void 0 : _a.call(evt);
2150
- setStart(null);
2151
- setCurrent(null);
2152
- }
2153
- }),
2154
- [
2155
- start,
2156
- current,
2157
- annotationProvides,
2158
- pageIndex,
2159
- pageWidthPDF,
2160
- pageHeightPDF,
2161
- toolColor,
2162
- toolOpacity,
2163
- toolStrokeWidth
2164
- ]
2165
- );
2166
- useEffect(() => register ? register(handlers) : void 0, [register, handlers]);
2167
- if (!start || !current) return null;
2168
- const minX = Math.min(start.x, current.x);
2169
- const minY = Math.min(start.y, current.y);
2170
- const maxX = Math.max(start.x, current.x);
2171
- const maxY = Math.max(start.y, current.y);
2172
- const halfStroke = toolStrokeWidth / 2;
2173
- const svgMinX = minX - halfStroke;
2174
- const svgMinY = minY - halfStroke;
2175
- const width = maxX - minX;
2176
- const height = maxY - minY;
2177
- const dw = width + toolStrokeWidth;
2178
- const dh = height + toolStrokeWidth;
2179
- const cx = halfStroke + width / 2;
2180
- const cy = halfStroke + height / 2;
2181
- const rx = width / 2;
2182
- const ry = height / 2;
2183
- return /* @__PURE__ */ jsx(
2184
- "svg",
2185
- {
2186
- style: {
2187
- position: "absolute",
2188
- left: svgMinX * scale,
2189
- top: svgMinY * scale,
2190
- width: dw * scale,
2191
- height: dh * scale,
2192
- pointerEvents: "none",
2193
- zIndex: 2
2194
- },
2195
- width: dw * scale,
2196
- height: dh * scale,
2197
- viewBox: `0 0 ${dw} ${dh}`,
2198
- children: /* @__PURE__ */ jsx(
2199
- "ellipse",
2200
- {
2201
- cx,
2202
- cy,
2203
- rx,
2204
- ry,
2205
- fill: toolColor,
2206
- opacity: toolOpacity,
2207
- style: {
2208
- cursor,
2209
- stroke: toolStrokeColor,
2210
- strokeWidth: toolStrokeWidth,
2211
- ...toolStrokeStyle === PdfAnnotationBorderStyle.DASHED && {
2212
- strokeDasharray: toolStrokeDashArray.join(",")
2213
- }
2214
- }
2215
- }
2216
- )
2217
- }
2218
- );
2219
- };
2220
- const SquarePaint = ({
2221
- pageIndex,
2222
- scale,
2223
- pageWidth,
2224
- pageHeight,
2225
- cursor
2226
- }) => {
2227
- const { provides: annotationProvides } = useAnnotationCapability();
2228
- const [activeTool, setActiveTool] = useState({ variantKey: null, defaults: null });
2229
- useEffect(() => {
2230
- if (!annotationProvides) return;
2231
- return annotationProvides.onActiveToolChange(setActiveTool);
2232
- }, [annotationProvides]);
2233
- if (!activeTool.defaults) return null;
2234
- if (activeTool.defaults.subtype !== PdfAnnotationSubtype.SQUARE) return null;
2235
- const toolColor = activeTool.defaults.color ?? "#000000";
2236
- const toolOpacity = activeTool.defaults.opacity ?? 1;
2237
- const toolStrokeWidth = activeTool.defaults.strokeWidth ?? 2;
2238
- const toolStrokeColor = activeTool.defaults.strokeColor ?? "#000000";
2239
- const toolStrokeStyle = activeTool.defaults.strokeStyle ?? PdfAnnotationBorderStyle.SOLID;
2240
- const toolStrokeDashArray = activeTool.defaults.strokeDashArray ?? [];
2241
- const { register } = usePointerHandlers({ modeId: "square", pageIndex });
2242
- const pageWidthPDF = pageWidth / scale;
2243
- const pageHeightPDF = pageHeight / scale;
2244
- const [start, setStart] = useState(null);
2245
- const [current, setCurrent] = useState(null);
2246
- const handlers = useMemo(
2247
- () => ({
2248
- onPointerDown: (pos, evt) => {
2249
- var _a, _b;
2250
- const x = clamp(pos.x, 0, pageWidthPDF);
2251
- const y = clamp(pos.y, 0, pageHeightPDF);
2252
- setStart({ x, y });
2253
- setCurrent({ x, y });
2254
- (_b = (_a = evt.target) == null ? void 0 : _a.setPointerCapture) == null ? void 0 : _b.call(_a, evt.pointerId);
2255
- },
2256
- onPointerMove: (pos) => {
2257
- if (!start) return;
2258
- const x = clamp(pos.x, 0, pageWidthPDF);
2259
- const y = clamp(pos.y, 0, pageHeightPDF);
2260
- setCurrent({ x, y });
2261
- },
2262
- onPointerUp: (_, evt) => {
2263
- var _a, _b;
2264
- if (start && current && annotationProvides) {
2265
- const minX2 = Math.min(start.x, current.x);
2266
- const minY2 = Math.min(start.y, current.y);
2267
- const maxX2 = Math.max(start.x, current.x);
2268
- const maxY2 = Math.max(start.y, current.y);
2269
- if (maxX2 - minX2 >= 1 && maxY2 - minY2 >= 1) {
2270
- const halfStroke2 = toolStrokeWidth / 2;
2271
- const rect = {
2272
- origin: { x: minX2 - halfStroke2, y: minY2 - halfStroke2 },
2273
- size: {
2274
- width: maxX2 - minX2 + toolStrokeWidth,
2275
- height: maxY2 - minY2 + toolStrokeWidth
2276
- }
2277
- };
2278
- const anno = {
2279
- type: PdfAnnotationSubtype.SQUARE,
2280
- rect,
2281
- flags: ["print"],
2282
- color: toolColor,
2283
- opacity: toolOpacity,
2284
- strokeWidth: toolStrokeWidth,
2285
- strokeColor: toolStrokeColor,
2286
- strokeStyle: toolStrokeStyle,
2287
- strokeDashArray: toolStrokeDashArray,
2288
- pageIndex,
2289
- id: uuidV4(),
2290
- created: /* @__PURE__ */ new Date()
2291
- };
2292
- annotationProvides.createAnnotation(pageIndex, anno);
2293
- annotationProvides.setActiveVariant(null);
2294
- annotationProvides.selectAnnotation(pageIndex, anno.id);
2295
- }
2296
- }
2297
- (_b = (_a = evt.target) == null ? void 0 : _a.releasePointerCapture) == null ? void 0 : _b.call(_a, evt.pointerId);
2298
- setStart(null);
2299
- setCurrent(null);
2300
- },
2301
- onPointerCancel: (_, evt) => {
2302
- var _a, _b;
2303
- (_b = (_a = evt.target) == null ? void 0 : _a.releasePointerCapture) == null ? void 0 : _b.call(_a, evt.pointerId);
2304
- setStart(null);
2305
- setCurrent(null);
2306
- }
2307
- }),
2308
- [
2309
- start,
2310
- current,
2311
- annotationProvides,
2312
- pageIndex,
2313
- pageWidthPDF,
2314
- pageHeightPDF,
2315
- toolColor,
2316
- toolOpacity,
2317
- toolStrokeWidth
2318
- ]
2319
- );
2320
- useEffect(() => register ? register(handlers) : void 0, [register, handlers]);
2321
- if (!start || !current) return null;
2322
- const minX = Math.min(start.x, current.x);
2323
- const minY = Math.min(start.y, current.y);
2324
- const maxX = Math.max(start.x, current.x);
2325
- const maxY = Math.max(start.y, current.y);
2326
- const halfStroke = toolStrokeWidth / 2;
2327
- const svgMinX = minX - halfStroke;
2328
- const svgMinY = minY - halfStroke;
2329
- const width = maxX - minX;
2330
- const height = maxY - minY;
2331
- const dw = width + toolStrokeWidth;
2332
- const dh = height + toolStrokeWidth;
2333
- return /* @__PURE__ */ jsx(
2334
- "svg",
2335
- {
2336
- style: {
2337
- position: "absolute",
2338
- left: svgMinX * scale,
2339
- top: svgMinY * scale,
2340
- width: dw * scale,
2341
- height: dh * scale,
2342
- pointerEvents: "none",
2343
- zIndex: 2
2344
- },
2345
- width: dw * scale,
2346
- height: dh * scale,
2347
- viewBox: `0 0 ${dw} ${dh}`,
2348
- children: /* @__PURE__ */ jsx(
2349
- "rect",
2350
- {
2351
- x: halfStroke,
2352
- y: halfStroke,
2353
- width,
2354
- height,
2355
- fill: toolColor,
2356
- opacity: toolOpacity,
2357
- style: {
2358
- cursor,
2359
- stroke: toolStrokeColor,
2360
- strokeWidth: toolStrokeWidth,
2361
- ...toolStrokeStyle === PdfAnnotationBorderStyle.DASHED && {
2362
- strokeDasharray: toolStrokeDashArray.join(",")
2363
- }
2364
- }
2365
- }
2366
- )
2367
- }
2368
- );
2369
- };
2370
- const PolylinePaint = ({
2371
- pageIndex,
2372
- scale,
2373
- pageWidth,
2374
- pageHeight,
2375
- cursor
2376
- }) => {
2377
- const { provides: annotationProvides } = useAnnotationCapability();
2378
- const [activeTool, setActiveTool] = useState({ variantKey: null, defaults: null });
2379
- useEffect(() => {
2380
- if (!annotationProvides) return;
2381
- return annotationProvides.onActiveToolChange(setActiveTool);
2382
- }, [annotationProvides]);
2383
- if (!activeTool.defaults) return null;
2384
- if (activeTool.defaults.subtype !== PdfAnnotationSubtype.POLYLINE) return null;
2385
- const toolColor = activeTool.defaults.color ?? "#000000";
2386
- const toolOpacity = activeTool.defaults.opacity ?? 1;
2387
- const toolStrokeWidth = activeTool.defaults.strokeWidth ?? 2;
2388
- const toolStrokeColor = activeTool.defaults.strokeColor ?? "#000000";
2389
- const toolLineEndings = activeTool.defaults.lineEndings;
2390
- const toolStrokeStyle = activeTool.defaults.strokeStyle ?? PdfAnnotationBorderStyle.SOLID;
2391
- const toolStrokeDashArray = activeTool.defaults.strokeDashArray;
2392
- const { register } = usePointerHandlers({ modeId: "polyline", pageIndex });
2393
- const pageWidthPDF = pageWidth / scale;
2394
- const pageHeightPDF = pageHeight / scale;
2395
- const [vertices, setVertices] = useState([]);
2396
- const [current, setCurrent] = useState(null);
2397
- const commitPolyline = (pts) => {
2398
- if (pts.length < 2) return;
2399
- const rect2 = patching.lineRectWithEndings(pts, toolStrokeWidth, toolLineEndings);
2400
- const anno = {
2401
- type: PdfAnnotationSubtype.POLYLINE,
2402
- rect: rect2,
2403
- vertices: pts,
2404
- color: toolColor,
2405
- opacity: toolOpacity,
2406
- strokeWidth: toolStrokeWidth,
2407
- strokeColor: toolStrokeColor,
2408
- strokeStyle: toolStrokeStyle,
2409
- strokeDashArray: toolStrokeDashArray,
2410
- lineEndings: toolLineEndings,
2411
- pageIndex,
2412
- id: uuidV4(),
2413
- created: /* @__PURE__ */ new Date()
2414
- };
2415
- annotationProvides.createAnnotation(pageIndex, anno);
2416
- annotationProvides.setActiveVariant(null);
2417
- annotationProvides.selectAnnotation(pageIndex, anno.id);
1542
+ function PreviewRenderer({ preview, scale }) {
1543
+ const { bounds } = preview;
1544
+ const style = {
1545
+ position: "absolute",
1546
+ left: bounds.origin.x * scale,
1547
+ top: bounds.origin.y * scale,
1548
+ width: bounds.size.width * scale,
1549
+ height: bounds.size.height * scale,
1550
+ pointerEvents: "none",
1551
+ zIndex: 10
2418
1552
  };
2419
- const handlers = useMemo(
2420
- () => ({
2421
- onClick: (pos) => {
2422
- const x = clamp(pos.x, 0, pageWidthPDF);
2423
- const y = clamp(pos.y, 0, pageHeightPDF);
2424
- setVertices((prev) => [...prev, { x, y }]);
2425
- setCurrent({ x, y });
2426
- },
2427
- onDoubleClick: () => {
2428
- if (vertices.length >= 1 && annotationProvides) {
2429
- commitPolyline(vertices);
2430
- }
2431
- setVertices([]);
2432
- setCurrent(null);
2433
- },
2434
- onPointerMove: (pos) => {
2435
- if (!vertices.length) return;
2436
- const x = clamp(pos.x, 0, pageWidthPDF);
2437
- const y = clamp(pos.y, 0, pageHeightPDF);
2438
- setCurrent({ x, y });
2439
- },
2440
- onPointerCancel: () => {
2441
- setVertices([]);
2442
- setCurrent(null);
2443
- }
2444
- }),
2445
- [vertices, annotationProvides, pageWidthPDF, pageHeightPDF]
2446
- );
2447
- useEffect(() => register ? register(handlers) : void 0, [register, handlers]);
2448
- if (!vertices.length || !current) return null;
2449
- const allPts = [...vertices, current];
2450
- const rect = patching.lineRectWithEndings(allPts, toolStrokeWidth, toolLineEndings);
2451
- return /* @__PURE__ */ jsx(
2452
- "div",
2453
- {
2454
- style: {
2455
- position: "absolute",
2456
- left: rect.origin.x * scale,
2457
- top: rect.origin.y * scale,
2458
- width: rect.size.width * scale,
2459
- height: rect.size.height * scale,
2460
- pointerEvents: "none",
2461
- zIndex: 2,
2462
- overflow: "visible",
2463
- cursor
2464
- },
2465
- children: /* @__PURE__ */ jsx(
2466
- Polyline,
2467
- {
2468
- rect,
2469
- vertices: allPts,
2470
- strokeWidth: toolStrokeWidth,
2471
- scale,
2472
- isSelected: false,
2473
- color: toolColor,
2474
- strokeColor: toolStrokeColor,
2475
- opacity: toolOpacity,
2476
- lineEndings: toolLineEndings
2477
- }
2478
- )
2479
- }
2480
- );
2481
- };
2482
- const LinePaint = ({ pageIndex, scale, pageWidth, pageHeight, cursor }) => {
2483
- const { provides: annotationProvides } = useAnnotationCapability();
2484
- const [activeTool, setActiveTool] = useState({ variantKey: null, defaults: null });
2485
- useEffect(() => {
2486
- if (!annotationProvides) return;
2487
- return annotationProvides.onActiveToolChange(setActiveTool);
2488
- }, [annotationProvides]);
2489
- if (!activeTool.defaults) return null;
2490
- if (activeTool.defaults.subtype !== PdfAnnotationSubtype.LINE) return null;
2491
- const toolColor = activeTool.defaults.color ?? "#000000";
2492
- const toolOpacity = activeTool.defaults.opacity ?? 1;
2493
- const toolStrokeWidth = activeTool.defaults.strokeWidth ?? 2;
2494
- const toolStrokeColor = activeTool.defaults.strokeColor ?? "#000000";
2495
- const toolStrokeStyle = activeTool.defaults.strokeStyle ?? PdfAnnotationBorderStyle.SOLID;
2496
- const toolStrokeDashArray = activeTool.defaults.strokeDashArray;
2497
- const toolLineEndings = activeTool.defaults.lineEndings;
2498
- const intent = activeTool.defaults.intent;
2499
- const { register } = usePointerHandlers({ modeId: ["line", "lineArrow"], pageIndex });
2500
- const pageWidthPDF = pageWidth / scale;
2501
- const pageHeightPDF = pageHeight / scale;
2502
- const [start, setStart] = useState(null);
2503
- const [current, setCurrent] = useState(null);
2504
- const commitLine = (p1, p2) => {
2505
- if (Math.abs(p2.x - p1.x) < 1 && Math.abs(p2.y - p1.y) < 1) return;
2506
- const rect2 = patching.lineRectWithEndings([p1, p2], toolStrokeWidth, toolLineEndings);
2507
- const anno = {
2508
- type: PdfAnnotationSubtype.LINE,
2509
- rect: rect2,
2510
- linePoints: { start: p1, end: p2 },
2511
- color: toolColor,
2512
- opacity: toolOpacity,
2513
- strokeWidth: toolStrokeWidth,
2514
- strokeColor: toolStrokeColor,
2515
- strokeStyle: toolStrokeStyle,
2516
- strokeDashArray: toolStrokeDashArray,
2517
- lineEndings: toolLineEndings,
2518
- intent,
2519
- pageIndex,
2520
- id: uuidV4(),
2521
- created: /* @__PURE__ */ new Date()
2522
- };
2523
- annotationProvides.createAnnotation(pageIndex, anno);
2524
- annotationProvides.setActiveVariant(null);
2525
- annotationProvides.selectAnnotation(pageIndex, anno.id);
2526
- };
2527
- const handlers = useMemo(
2528
- () => ({
2529
- onPointerDown: (pos, evt) => {
2530
- var _a;
2531
- const x = clamp(pos.x, 0, pageWidthPDF);
2532
- const y = clamp(pos.y, 0, pageHeightPDF);
2533
- setStart({ x, y });
2534
- setCurrent({ x, y });
2535
- (_a = evt.setPointerCapture) == null ? void 0 : _a.call(evt);
2536
- },
2537
- onPointerMove: (pos) => {
2538
- if (!start) return;
2539
- const x = clamp(pos.x, 0, pageWidthPDF);
2540
- const y = clamp(pos.y, 0, pageHeightPDF);
2541
- setCurrent({ x, y });
2542
- },
2543
- onPointerUp: (_, evt) => {
2544
- var _a;
2545
- if (start && current && annotationProvides) {
2546
- commitLine(start, current);
1553
+ if (preview.type === PdfAnnotationSubtype.CIRCLE) {
1554
+ return /* @__PURE__ */ jsx("div", { style, children: /* @__PURE__ */ jsx(Circle, { isSelected: false, scale, ...preview.data }) });
1555
+ }
1556
+ if (preview.type === PdfAnnotationSubtype.SQUARE) {
1557
+ return /* @__PURE__ */ jsx("div", { style, children: /* @__PURE__ */ jsx(Square, { isSelected: false, scale, ...preview.data }) });
1558
+ }
1559
+ if (preview.type === PdfAnnotationSubtype.POLYGON) {
1560
+ return /* @__PURE__ */ jsx("div", { style, children: /* @__PURE__ */ jsx(Polygon, { isSelected: false, scale, ...preview.data }) });
1561
+ }
1562
+ if (preview.type === PdfAnnotationSubtype.POLYLINE) {
1563
+ return /* @__PURE__ */ jsx("div", { style, children: /* @__PURE__ */ jsx(Polyline, { isSelected: false, scale, ...preview.data }) });
1564
+ }
1565
+ if (preview.type === PdfAnnotationSubtype.LINE) {
1566
+ return /* @__PURE__ */ jsx("div", { style, children: /* @__PURE__ */ jsx(Line, { isSelected: false, scale, ...preview.data }) });
1567
+ }
1568
+ if (preview.type === PdfAnnotationSubtype.INK) {
1569
+ return /* @__PURE__ */ jsx("div", { style, children: /* @__PURE__ */ jsx(Ink, { isSelected: false, scale, ...preview.data }) });
1570
+ }
1571
+ if (preview.type === PdfAnnotationSubtype.FREETEXT) {
1572
+ return /* @__PURE__ */ jsx("div", { style, children: /* @__PURE__ */ jsx(
1573
+ "div",
1574
+ {
1575
+ style: {
1576
+ width: "100%",
1577
+ height: "100%",
1578
+ border: `1px dashed ${preview.data.fontColor || "#000000"}`,
1579
+ backgroundColor: "transparent"
2547
1580
  }
2548
- (_a = evt.releasePointerCapture) == null ? void 0 : _a.call(evt);
2549
- setStart(null);
2550
- setCurrent(null);
2551
- },
2552
- onPointerCancel: (_, evt) => {
2553
- var _a;
2554
- (_a = evt.releasePointerCapture) == null ? void 0 : _a.call(evt);
2555
- setStart(null);
2556
- setCurrent(null);
2557
1581
  }
2558
- }),
2559
- [start, current, annotationProvides, pageWidthPDF, pageHeightPDF]
2560
- );
2561
- useEffect(() => register ? register(handlers) : void 0, [register, handlers]);
2562
- if (!start || !current) return null;
2563
- const rect = patching.lineRectWithEndings([start, current], toolStrokeWidth, toolLineEndings);
2564
- return /* @__PURE__ */ jsx(
2565
- "div",
2566
- {
2567
- style: {
2568
- position: "absolute",
2569
- left: rect.origin.x * scale,
2570
- top: rect.origin.y * scale,
2571
- width: rect.size.width * scale,
2572
- height: rect.size.height * scale,
2573
- pointerEvents: "none",
2574
- zIndex: 2,
2575
- overflow: "visible",
2576
- cursor
2577
- },
2578
- children: /* @__PURE__ */ jsx(
2579
- Line,
2580
- {
2581
- rect,
2582
- linePoints: { start, end: current },
2583
- strokeWidth: toolStrokeWidth,
2584
- scale,
2585
- isSelected: false,
2586
- color: toolColor,
2587
- strokeColor: toolStrokeColor,
2588
- opacity: toolOpacity,
2589
- lineEndings: toolLineEndings,
2590
- strokeStyle: toolStrokeStyle,
2591
- strokeDashArray: toolStrokeDashArray
2592
- }
2593
- )
2594
- }
2595
- );
2596
- };
2597
- const HANDLE_SIZE_PX = 14;
2598
- const PolygonPaint = ({
2599
- pageIndex,
2600
- scale,
2601
- pageWidth,
2602
- pageHeight,
2603
- cursor
2604
- }) => {
2605
- const { provides: annotationProvides } = useAnnotationCapability();
2606
- const [activeTool, setActiveTool] = useState({ variantKey: null, defaults: null });
2607
- useEffect(() => annotationProvides == null ? void 0 : annotationProvides.onActiveToolChange(setActiveTool), [annotationProvides]);
2608
- if (!activeTool.defaults || activeTool.defaults.subtype !== PdfAnnotationSubtype.POLYGON)
2609
- return null;
2610
- const toolColor = activeTool.defaults.color ?? "#000000";
2611
- const toolOpacity = activeTool.defaults.opacity ?? 1;
2612
- const toolStrokeWidth = activeTool.defaults.strokeWidth ?? 2;
2613
- const toolStrokeColor = activeTool.defaults.strokeColor ?? "#000000";
2614
- const toolStrokeStyle = activeTool.defaults.strokeStyle ?? PdfAnnotationBorderStyle.SOLID;
2615
- const toolStrokeDashArray = activeTool.defaults.strokeDashArray;
2616
- const { register } = usePointerHandlers({ modeId: "polygon", pageIndex });
2617
- const pageWidthPDF = pageWidth / scale;
2618
- const pageHeightPDF = pageHeight / scale;
2619
- const [vertices, setVertices] = useState([]);
2620
- const [current, setCurrent] = useState(null);
2621
- const commitPolygon = (pts) => {
2622
- const xs2 = pts.map((p) => p.x), ys2 = pts.map((p) => p.y);
2623
- const minX2 = Math.min(...xs2), minY2 = Math.min(...ys2);
2624
- const maxX2 = Math.max(...xs2), maxY2 = Math.max(...ys2);
2625
- if (maxX2 - minX2 < 1 || maxY2 - minY2 < 1) return;
2626
- const half2 = toolStrokeWidth / 2;
2627
- const rect = {
2628
- origin: { x: minX2 - half2, y: minY2 - half2 },
2629
- size: { width: maxX2 - minX2 + toolStrokeWidth, height: maxY2 - minY2 + toolStrokeWidth }
2630
- };
2631
- const anno = {
2632
- type: PdfAnnotationSubtype.POLYGON,
2633
- rect,
2634
- vertices: pts,
2635
- color: toolColor,
2636
- opacity: toolOpacity,
2637
- strokeWidth: toolStrokeWidth,
2638
- strokeColor: toolStrokeColor,
2639
- strokeStyle: toolStrokeStyle,
2640
- strokeDashArray: toolStrokeDashArray,
2641
- pageIndex,
2642
- id: uuidV4(),
2643
- created: /* @__PURE__ */ new Date()
2644
- };
2645
- annotationProvides.createAnnotation(pageIndex, anno);
2646
- annotationProvides.setActiveVariant(null);
2647
- annotationProvides.selectAnnotation(pageIndex, anno.id);
2648
- };
2649
- const isInsideStartHandle = (x, y) => {
2650
- if (vertices.length < 2) return false;
2651
- const sizePDF = HANDLE_SIZE_PX / scale;
2652
- const half2 = sizePDF / 2;
2653
- const v0 = vertices[0];
2654
- return x >= v0.x - half2 && x <= v0.x + half2 && y >= v0.y - half2 && y <= v0.y + half2;
2655
- };
2656
- const handlers = useMemo(
1582
+ ) });
1583
+ }
1584
+ return null;
1585
+ }
1586
+ function AnnotationPaintLayer({ pageIndex, scale }) {
1587
+ const { plugin: annotationPlugin } = useAnnotationPlugin();
1588
+ const [previews, setPreviews] = useState(/* @__PURE__ */ new Map());
1589
+ const fileInputRef = useRef(null);
1590
+ const canvasRef = useRef(null);
1591
+ const services = useMemo(
2657
1592
  () => ({
2658
- onClick: (pos) => {
2659
- const x = clamp(pos.x, 0, pageWidthPDF);
2660
- const y = clamp(pos.y, 0, pageHeightPDF);
2661
- if (isInsideStartHandle(x, y) && vertices.length >= 3 && annotationProvides) {
2662
- commitPolygon(vertices);
2663
- setVertices([]);
2664
- setCurrent(null);
2665
- return;
2666
- }
2667
- setVertices((prev) => [...prev, { x, y }]);
2668
- setCurrent({ x, y });
2669
- },
2670
- onDoubleClick: () => {
2671
- if (vertices.length >= 3 && annotationProvides) {
2672
- commitPolygon(vertices);
2673
- setVertices([]);
2674
- setCurrent(null);
2675
- } else {
2676
- setVertices([]);
2677
- setCurrent(null);
2678
- }
2679
- },
2680
- onPointerMove: (pos) => {
2681
- if (!vertices.length) return;
2682
- const x = clamp(pos.x, 0, pageWidthPDF);
2683
- const y = clamp(pos.y, 0, pageHeightPDF);
2684
- setCurrent({ x, y });
2685
- },
2686
- onPointerCancel: () => {
2687
- setVertices([]);
2688
- setCurrent(null);
2689
- }
2690
- }),
2691
- [vertices, current, annotationProvides, pageWidthPDF, pageHeightPDF]
2692
- );
2693
- useEffect(() => register ? register(handlers) : void 0, [register, handlers]);
2694
- if (!vertices.length || !current) return null;
2695
- const allPts = [...vertices, current];
2696
- const xs = allPts.map((p) => p.x), ys = allPts.map((p) => p.y);
2697
- const minX = Math.min(...xs), minY = Math.min(...ys);
2698
- const maxX = Math.max(...xs), maxY = Math.max(...ys);
2699
- const half = toolStrokeWidth / 2;
2700
- const svgMinX = minX - half;
2701
- const svgMinY = minY - half;
2702
- const svgMaxX = maxX + half;
2703
- const svgMaxY = maxY + half;
2704
- const dw = svgMaxX - svgMinX;
2705
- const dh = svgMaxY - svgMinY;
2706
- const mainPath = useMemo(() => {
2707
- let d = "";
2708
- allPts.forEach(({ x, y }, i) => {
2709
- d += (i === 0 ? "M" : "L") + (x - svgMinX) + " " + (y - svgMinY) + " ";
2710
- });
2711
- return d.trim();
2712
- }, [allPts, svgMinX, svgMinY]);
2713
- const dottedPath = vertices.length >= 2 ? (() => {
2714
- const curLx = current.x - svgMinX;
2715
- const curLy = current.y - svgMinY;
2716
- const firstLx = vertices[0].x - svgMinX;
2717
- const firstLy = vertices[0].y - svgMinY;
2718
- return `M ${curLx} ${curLy} L ${firstLx} ${firstLy}`;
2719
- })() : null;
2720
- const handleSizePDF = HANDLE_SIZE_PX / scale;
2721
- const hHalf = handleSizePDF / 2;
2722
- const hx = vertices[0].x - hHalf - svgMinX;
2723
- const hy = vertices[0].y - hHalf - svgMinY;
2724
- return /* @__PURE__ */ jsxs(
2725
- "svg",
2726
- {
2727
- style: {
2728
- position: "absolute",
2729
- left: svgMinX * scale,
2730
- top: svgMinY * scale,
2731
- width: dw * scale,
2732
- height: dh * scale,
2733
- pointerEvents: "none",
2734
- // we handle clicks at the page layer
2735
- zIndex: 2,
2736
- overflow: "visible"
2737
- },
2738
- width: dw * scale,
2739
- height: dh * scale,
2740
- viewBox: `0 0 ${dw} ${dh}`,
2741
- children: [
2742
- /* @__PURE__ */ jsx(
2743
- "path",
2744
- {
2745
- d: mainPath,
2746
- fill: toolColor,
2747
- opacity: toolOpacity,
2748
- style: {
2749
- cursor,
2750
- stroke: toolStrokeColor,
2751
- strokeWidth: toolStrokeWidth,
2752
- ...toolStrokeStyle === PdfAnnotationBorderStyle.DASHED && {
2753
- strokeDasharray: toolStrokeDashArray == null ? void 0 : toolStrokeDashArray.join(",")
2754
- }
2755
- }
2756
- }
2757
- ),
2758
- dottedPath && /* @__PURE__ */ jsx(
2759
- "path",
2760
- {
2761
- d: dottedPath,
2762
- fill: "none",
2763
- style: { stroke: toolStrokeColor, strokeWidth: toolStrokeWidth, strokeDasharray: "4,4" }
2764
- }
2765
- ),
2766
- vertices.length >= 3 && /* @__PURE__ */ jsx(
2767
- "rect",
2768
- {
2769
- x: hx,
2770
- y: hy,
2771
- width: handleSizePDF,
2772
- height: handleSizePDF,
2773
- fill: toolStrokeColor,
2774
- opacity: 0.4,
2775
- stroke: toolStrokeColor,
2776
- strokeWidth: toolStrokeWidth / 2,
2777
- style: { pointerEvents: "none" }
1593
+ requestFile: ({ accept, onFile }) => {
1594
+ if (!fileInputRef.current) return;
1595
+ const input = fileInputRef.current;
1596
+ input.accept = accept;
1597
+ input.onchange = (e) => {
1598
+ var _a;
1599
+ const file = (_a = e.target.files) == null ? void 0 : _a[0];
1600
+ if (file) {
1601
+ onFile(file);
1602
+ input.value = "";
2778
1603
  }
2779
- )
2780
- ]
2781
- }
2782
- );
2783
- };
2784
- const FreeTextPaint = ({
2785
- pageIndex,
2786
- scale,
2787
- pageWidth,
2788
- pageHeight,
2789
- cursor = "text"
2790
- }) => {
2791
- const { provides: annotationProvides } = useAnnotationCapability();
2792
- const [activeTool, setActiveTool] = useState({ variantKey: null, defaults: null });
2793
- useEffect(() => annotationProvides == null ? void 0 : annotationProvides.onActiveToolChange(setActiveTool), [annotationProvides]);
2794
- if (!activeTool.defaults || activeTool.defaults.subtype !== PdfAnnotationSubtype.FREETEXT)
2795
- return null;
2796
- const toolFontColor = activeTool.defaults.fontColor ?? "#000000";
2797
- const toolOpacity = activeTool.defaults.opacity ?? 1;
2798
- const toolFontSize = activeTool.defaults.fontSize ?? 12;
2799
- const toolFontFamily = activeTool.defaults.fontFamily;
2800
- const toolBackgroundColor = activeTool.defaults.backgroundColor ?? "transparent";
2801
- const toolTextAlign = activeTool.defaults.textAlign;
2802
- const toolVerticalAlign = activeTool.defaults.verticalAlign;
2803
- const toolContent = activeTool.defaults.content ?? "Insert text here";
2804
- const { register } = usePointerHandlers({ modeId: "freeText", pageIndex });
2805
- const clamp2 = (v, min, max) => Math.max(min, Math.min(max, v));
2806
- const pageWidthPDF = pageWidth / scale;
2807
- const pageHeightPDF = pageHeight / scale;
2808
- const [start, setStart] = useState(null);
2809
- const [current, setCurrent] = useState(null);
2810
- const commitFreeText = (p1, p2) => {
2811
- const minX2 = Math.min(p1.x, p2.x);
2812
- const minY2 = Math.min(p1.y, p2.y);
2813
- const maxX2 = Math.max(p1.x, p2.x);
2814
- const maxY2 = Math.max(p1.y, p2.y);
2815
- const w = maxX2 - minX2;
2816
- const h = maxY2 - minY2;
2817
- if (w < 1 || h < 1) return;
2818
- const rect = {
2819
- origin: { x: minX2, y: minY2 },
2820
- size: { width: w, height: h }
2821
- };
2822
- const anno = {
2823
- type: PdfAnnotationSubtype.FREETEXT,
2824
- rect,
2825
- contents: toolContent,
2826
- fontColor: toolFontColor,
2827
- fontSize: toolFontSize,
2828
- fontFamily: toolFontFamily,
2829
- opacity: toolOpacity,
2830
- backgroundColor: toolBackgroundColor,
2831
- textAlign: toolTextAlign,
2832
- verticalAlign: toolVerticalAlign,
2833
- pageIndex,
2834
- id: uuidV4(),
2835
- created: /* @__PURE__ */ new Date()
2836
- };
2837
- annotationProvides.createAnnotation(pageIndex, anno);
2838
- annotationProvides.setActiveVariant(null);
2839
- annotationProvides.selectAnnotation(pageIndex, anno.id);
2840
- };
2841
- const handlers = useMemo(
2842
- () => ({
2843
- onPointerDown: (pos, evt) => {
2844
- var _a;
2845
- const x = clamp2(pos.x, 0, pageWidthPDF);
2846
- const y = clamp2(pos.y, 0, pageHeightPDF);
2847
- setStart({ x, y });
2848
- setCurrent({ x, y });
2849
- (_a = evt.setPointerCapture) == null ? void 0 : _a.call(evt);
1604
+ };
1605
+ input.click();
2850
1606
  },
2851
- onPointerMove: (pos) => {
2852
- if (!start) return;
2853
- const x = clamp2(pos.x, 0, pageWidthPDF);
2854
- const y = clamp2(pos.y, 0, pageHeightPDF);
2855
- setCurrent({ x, y });
2856
- },
2857
- onPointerUp: (_, evt) => {
2858
- var _a;
2859
- if (start && current && annotationProvides) {
2860
- commitFreeText(start, current);
2861
- }
2862
- (_a = evt.releasePointerCapture) == null ? void 0 : _a.call(evt);
2863
- setStart(null);
2864
- setCurrent(null);
2865
- },
2866
- onPointerCancel: (_, evt) => {
2867
- var _a;
2868
- (_a = evt.releasePointerCapture) == null ? void 0 : _a.call(evt);
2869
- setStart(null);
2870
- setCurrent(null);
1607
+ processImage: ({ source, maxWidth, maxHeight, onComplete }) => {
1608
+ const canvas = canvasRef.current;
1609
+ if (!canvas || !canvas.getContext) return;
1610
+ const ctx = canvas.getContext("2d");
1611
+ if (!ctx) return;
1612
+ const img = new Image();
1613
+ img.crossOrigin = "Anonymous";
1614
+ img.onload = () => {
1615
+ let { naturalWidth: width, naturalHeight: height } = img;
1616
+ const scaleX = maxWidth ? maxWidth / width : 1;
1617
+ const scaleY = maxHeight ? maxHeight / height : 1;
1618
+ const scaleFactor = Math.min(scaleX, scaleY, 1);
1619
+ const finalWidth = width * scaleFactor;
1620
+ const finalHeight = height * scaleFactor;
1621
+ canvas.width = finalWidth;
1622
+ canvas.height = finalHeight;
1623
+ ctx.drawImage(img, 0, 0, finalWidth, finalHeight);
1624
+ const imageData = ctx.getImageData(0, 0, finalWidth, finalHeight);
1625
+ if (typeof source !== "string") URL.revokeObjectURL(img.src);
1626
+ onComplete({ imageData, width: finalWidth, height: finalHeight });
1627
+ };
1628
+ img.src = typeof source === "string" ? source : URL.createObjectURL(source);
2871
1629
  }
2872
1630
  }),
2873
- [start, current, annotationProvides, pageWidthPDF, pageHeightPDF]
1631
+ []
2874
1632
  );
2875
- useEffect(() => register ? register(handlers) : void 0, [register, handlers]);
2876
- if (!start || !current) return null;
2877
- const minX = Math.min(start.x, current.x);
2878
- const minY = Math.min(start.y, current.y);
2879
- const maxX = Math.max(start.x, current.x);
2880
- const maxY = Math.max(start.y, current.y);
2881
- const dw = maxX - minX;
2882
- const dh = maxY - minY;
2883
- return /* @__PURE__ */ jsx(
2884
- "svg",
2885
- {
2886
- style: {
2887
- position: "absolute",
2888
- left: minX * scale,
2889
- top: minY * scale,
2890
- width: dw * scale,
2891
- height: dh * scale,
2892
- pointerEvents: "none",
2893
- zIndex: 2
2894
- },
2895
- width: dw * scale,
2896
- height: dh * scale,
2897
- viewBox: `0 0 ${dw} ${dh}`,
2898
- children: /* @__PURE__ */ jsx(
2899
- "rect",
2900
- {
2901
- x: 0,
2902
- y: 0,
2903
- width: dw,
2904
- height: dh,
2905
- fill: "transparent",
2906
- style: {
2907
- stroke: toolFontColor,
2908
- strokeWidth: 1,
2909
- strokeDasharray: "4,4",
2910
- cursor
2911
- }
2912
- }
2913
- )
2914
- }
2915
- );
2916
- };
2917
- const StampPaint = ({ pageIndex, scale, pageWidth, pageHeight }) => {
2918
- const { provides: annotationProvides } = useAnnotationCapability();
2919
- const inputRef = useRef(null);
2920
- const canvasRef = useRef(null);
2921
- const [activeTool, setActiveTool] = useState({ variantKey: null, defaults: null });
2922
1633
  useEffect(() => {
2923
- if (!annotationProvides) return;
2924
- return annotationProvides.onActiveToolChange(setActiveTool);
2925
- }, [annotationProvides]);
2926
- if (!activeTool.defaults) return null;
2927
- if (activeTool.defaults.subtype !== PdfAnnotationSubtype.STAMP) return null;
2928
- const { register } = usePointerHandlers({ modeId: "stamp", pageIndex });
2929
- const pageWidthPDF = pageWidth / scale;
2930
- const pageHeightPDF = pageHeight / scale;
2931
- const [start, setStart] = useState(null);
2932
- const handlers = useMemo(
2933
- () => ({
2934
- onPointerDown: (pos, evt) => {
2935
- var _a;
2936
- const x = clamp(pos.x, 0, pageWidthPDF);
2937
- const y = clamp(pos.y, 0, pageHeightPDF);
2938
- setStart({ x, y });
2939
- (_a = inputRef.current) == null ? void 0 : _a.click();
1634
+ if (!annotationPlugin) return;
1635
+ return annotationPlugin.registerPageHandlers(pageIndex, scale, {
1636
+ services,
1637
+ onPreview: (toolId, state) => {
1638
+ setPreviews((prev) => {
1639
+ const next = new Map(prev);
1640
+ if (state) {
1641
+ next.set(toolId, state);
1642
+ } else {
1643
+ next.delete(toolId);
1644
+ }
1645
+ return next;
1646
+ });
2940
1647
  }
2941
- }),
2942
- [pageWidthPDF, pageHeightPDF]
2943
- );
2944
- useEffect(() => register ? register(handlers) : void 0, [register, handlers]);
2945
- const onChange = async (e) => {
2946
- var _a;
2947
- if (!annotationProvides || !start) return;
2948
- const file = (_a = e.currentTarget.files) == null ? void 0 : _a[0];
2949
- if (!file) return;
2950
- const img = await new Promise((res, rej) => {
2951
- const i = new Image();
2952
- i.onload = () => res(i);
2953
- i.onerror = rej;
2954
- i.src = URL.createObjectURL(file);
2955
1648
  });
2956
- const imgW = img.naturalWidth;
2957
- const imgH = img.naturalHeight;
2958
- const maxW = pageWidthPDF;
2959
- const maxH = pageHeightPDF;
2960
- const scaleFactor = Math.min(1, maxW / imgW, maxH / imgH);
2961
- const pdfW = imgW * scaleFactor;
2962
- const pdfH = imgH * scaleFactor;
2963
- const posX = clamp(start.x, 0, maxW - pdfW);
2964
- const posY = clamp(start.y, 0, maxH - pdfH);
2965
- const rect = {
2966
- origin: { x: posX, y: posY },
2967
- size: { width: pdfW, height: pdfH }
2968
- };
2969
- const canvas = canvasRef.current;
2970
- if (!canvas) return;
2971
- canvas.width = pdfW;
2972
- canvas.height = pdfH;
2973
- const ctx = canvas.getContext("2d");
2974
- ctx.drawImage(img, 0, 0, pdfW, pdfH);
2975
- const imageData = ctx.getImageData(0, 0, pdfW, pdfH);
2976
- const anno = {
2977
- type: PdfAnnotationSubtype.STAMP,
2978
- flags: ["print"],
2979
- pageIndex,
2980
- id: uuidV4(),
2981
- created: /* @__PURE__ */ new Date(),
2982
- rect
2983
- };
2984
- annotationProvides.createAnnotation(pageIndex, anno, { imageData });
2985
- annotationProvides.setActiveVariant(null);
2986
- annotationProvides.selectAnnotation(pageIndex, anno.id);
2987
- setStart(null);
2988
- };
1649
+ }, [pageIndex, scale, annotationPlugin, services]);
2989
1650
  return /* @__PURE__ */ jsxs(Fragment, { children: [
2990
- /* @__PURE__ */ jsx("canvas", { style: { display: "none" }, ref: canvasRef }),
2991
- /* @__PURE__ */ jsx(
2992
- "input",
2993
- {
2994
- ref: inputRef,
2995
- type: "file",
2996
- accept: "image/png,image/jpeg",
2997
- style: { display: "none" },
2998
- onChange
2999
- }
3000
- )
1651
+ /* @__PURE__ */ jsx("input", { ref: fileInputRef, type: "file", style: { display: "none" } }),
1652
+ /* @__PURE__ */ jsx("canvas", { ref: canvasRef, style: { display: "none" } }),
1653
+ Array.from(previews.entries()).map(([toolId, preview]) => /* @__PURE__ */ jsx(PreviewRenderer, { preview, scale }, toolId))
3001
1654
  ] });
3002
- };
1655
+ }
3003
1656
  function AnnotationLayer({
1657
+ style,
3004
1658
  pageIndex,
3005
1659
  scale,
1660
+ selectionMenu,
1661
+ resizeUI,
1662
+ vertexUI,
3006
1663
  pageWidth,
3007
1664
  pageHeight,
3008
1665
  rotation,
3009
- selectionMenu,
3010
- style,
1666
+ selectionOutlineColor,
3011
1667
  ...props
3012
1668
  }) {
3013
1669
  return /* @__PURE__ */ jsxs(
@@ -3026,74 +1682,14 @@ function AnnotationLayer({
3026
1682
  scale,
3027
1683
  rotation,
3028
1684
  pageWidth,
3029
- pageHeight
1685
+ pageHeight,
1686
+ resizeUI,
1687
+ vertexUI,
1688
+ selectionOutlineColor
3030
1689
  }
3031
1690
  ),
3032
1691
  /* @__PURE__ */ jsx(TextMarkup, { pageIndex, scale }),
3033
- /* @__PURE__ */ jsx(InkPaint, { pageIndex, scale, pageWidth, pageHeight }),
3034
- /* @__PURE__ */ jsx(
3035
- CirclePaint,
3036
- {
3037
- pageIndex,
3038
- scale,
3039
- pageWidth,
3040
- pageHeight
3041
- }
3042
- ),
3043
- /* @__PURE__ */ jsx(
3044
- SquarePaint,
3045
- {
3046
- pageIndex,
3047
- scale,
3048
- pageWidth,
3049
- pageHeight
3050
- }
3051
- ),
3052
- /* @__PURE__ */ jsx(
3053
- PolygonPaint,
3054
- {
3055
- pageIndex,
3056
- scale,
3057
- pageWidth,
3058
- pageHeight
3059
- }
3060
- ),
3061
- /* @__PURE__ */ jsx(
3062
- PolylinePaint,
3063
- {
3064
- pageIndex,
3065
- scale,
3066
- pageWidth,
3067
- pageHeight
3068
- }
3069
- ),
3070
- /* @__PURE__ */ jsx(
3071
- LinePaint,
3072
- {
3073
- pageIndex,
3074
- scale,
3075
- pageWidth,
3076
- pageHeight
3077
- }
3078
- ),
3079
- /* @__PURE__ */ jsx(
3080
- FreeTextPaint,
3081
- {
3082
- pageIndex,
3083
- scale,
3084
- pageWidth,
3085
- pageHeight
3086
- }
3087
- ),
3088
- /* @__PURE__ */ jsx(
3089
- StampPaint,
3090
- {
3091
- pageIndex,
3092
- scale,
3093
- pageWidth,
3094
- pageHeight
3095
- }
3096
- )
1692
+ /* @__PURE__ */ jsx(AnnotationPaintLayer, { pageIndex, scale })
3097
1693
  ]
3098
1694
  }
3099
1695
  );