@embedpdf/plugin-annotation 1.1.0 → 1.2.0

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