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