@embedpdf/plugin-annotation 2.13.0 → 2.14.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (53) hide show
  1. package/dist/index.cjs +1 -1
  2. package/dist/index.cjs.map +1 -1
  3. package/dist/index.js +522 -7
  4. package/dist/index.js.map +1 -1
  5. package/dist/lib/annotation-plugin.d.ts +25 -0
  6. package/dist/lib/handlers/callout-free-text.handler.d.ts +3 -0
  7. package/dist/lib/handlers/index.d.ts +1 -0
  8. package/dist/lib/handlers/types.d.ts +7 -1
  9. package/dist/lib/helpers.d.ts +8 -0
  10. package/dist/lib/patching/patch-utils.d.ts +38 -1
  11. package/dist/lib/patching/patches/callout-freetext.patch.d.ts +3 -0
  12. package/dist/lib/patching/patches/index.d.ts +1 -0
  13. package/dist/lib/tools/default-tools.d.ts +35 -0
  14. package/dist/lib/types.d.ts +21 -2
  15. package/dist/preact/index.cjs +1 -1
  16. package/dist/preact/index.cjs.map +1 -1
  17. package/dist/preact/index.js +422 -32
  18. package/dist/preact/index.js.map +1 -1
  19. package/dist/react/index.cjs +1 -1
  20. package/dist/react/index.cjs.map +1 -1
  21. package/dist/react/index.js +422 -32
  22. package/dist/react/index.js.map +1 -1
  23. package/dist/shared/components/annotation-container.d.ts +13 -1
  24. package/dist/shared/components/annotations/callout-free-text-preview.d.ts +15 -0
  25. package/dist/shared/components/annotations/callout-free-text.d.ts +15 -0
  26. package/dist/shared/components/types.d.ts +12 -0
  27. package/dist/shared-preact/components/annotation-container.d.ts +13 -1
  28. package/dist/shared-preact/components/annotations/callout-free-text-preview.d.ts +15 -0
  29. package/dist/shared-preact/components/annotations/callout-free-text.d.ts +15 -0
  30. package/dist/shared-preact/components/types.d.ts +12 -0
  31. package/dist/shared-react/components/annotation-container.d.ts +13 -1
  32. package/dist/shared-react/components/annotations/callout-free-text-preview.d.ts +15 -0
  33. package/dist/shared-react/components/annotations/callout-free-text.d.ts +15 -0
  34. package/dist/shared-react/components/types.d.ts +12 -0
  35. package/dist/svelte/components/annotations/CalloutFreeText.svelte.d.ts +15 -0
  36. package/dist/svelte/components/annotations/CalloutFreeTextPreview.svelte.d.ts +10 -0
  37. package/dist/svelte/components/renderers/CalloutFreeTextRenderer.svelte.d.ts +5 -0
  38. package/dist/svelte/components/types.d.ts +12 -0
  39. package/dist/svelte/index.cjs +1 -1
  40. package/dist/svelte/index.cjs.map +1 -1
  41. package/dist/svelte/index.js +528 -106
  42. package/dist/svelte/index.js.map +1 -1
  43. package/dist/svelte/types.d.ts +12 -0
  44. package/dist/vue/components/annotation-container.vue.d.ts +12 -0
  45. package/dist/vue/components/annotations/callout-free-text-preview.vue.d.ts +10 -0
  46. package/dist/vue/components/annotations/callout-free-text.vue.d.ts +25 -0
  47. package/dist/vue/components/renderers/callout-free-text-renderer.vue.d.ts +6 -0
  48. package/dist/vue/index.cjs +1 -1
  49. package/dist/vue/index.cjs.map +1 -1
  50. package/dist/vue/index.js +601 -211
  51. package/dist/vue/index.js.map +1 -1
  52. package/dist/vue/types.d.ts +12 -0
  53. package/package.json +12 -12
@@ -1,5 +1,5 @@
1
1
  import { createPluginPackage } from "@embedpdf/core";
2
- import { AnnotationPlugin, initialDocumentState, generateCloudyRectanglePath, generateCloudyEllipsePath, patching, generateCloudyPolygonPath, LockModeType, getAnnotationsByPageIndex, getSelectedAnnotationIds, resolveInteractionProp, getAnnotationCategories, hasLockedFlag, isCategoryLocked, AnnotationPluginPackage as AnnotationPluginPackage$1 } from "@embedpdf/plugin-annotation";
2
+ import { AnnotationPlugin, initialDocumentState, generateCloudyRectanglePath, generateCloudyEllipsePath, patching, generateCloudyPolygonPath, LockModeType, getAnnotationsByPageIndex, getSelectedAnnotationIds, resolveInteractionProp, hasNoViewFlag, hasHiddenFlag, AnnotationPluginPackage as AnnotationPluginPackage$1 } from "@embedpdf/plugin-annotation";
3
3
  export * from "@embedpdf/plugin-annotation";
4
4
  import { jsx, jsxs, Fragment } from "react/jsx-runtime";
5
5
  import { createContext, useState, useCallback, useContext, useRef, useEffect, useMemo, Fragment as Fragment$1 } from "react";
@@ -162,6 +162,8 @@ function AnnotationContainer({
162
162
  blendMode,
163
163
  vertexConfig,
164
164
  selectionMenu,
165
+ structurallyLocked = false,
166
+ contentLocked = false,
165
167
  outlineOffset = 1,
166
168
  onDoubleClick,
167
169
  onSelect,
@@ -682,7 +684,9 @@ function AnnotationContainer({
682
684
  context: {
683
685
  type: "annotation",
684
686
  annotation: trackedAnnotation,
685
- pageIndex
687
+ pageIndex,
688
+ structurallyLocked,
689
+ contentLocked
686
690
  },
687
691
  selected: isSelected,
688
692
  placement: {
@@ -1276,7 +1280,7 @@ function createRenderer(entry) {
1276
1280
  renderLocked: entry.renderLocked ? (props) => entry.renderLocked(props) : void 0
1277
1281
  };
1278
1282
  }
1279
- const MIN_HIT_AREA_SCREEN_PX$5 = 20;
1283
+ const MIN_HIT_AREA_SCREEN_PX$6 = 20;
1280
1284
  function Ink({
1281
1285
  isSelected,
1282
1286
  strokeColor,
@@ -1302,7 +1306,7 @@ function Ink({
1302
1306
  }, [inkList, rect]);
1303
1307
  const width = rect.size.width * scale;
1304
1308
  const height = rect.size.height * scale;
1305
- const hitStrokeWidth = Math.max(strokeWidth, MIN_HIT_AREA_SCREEN_PX$5 / scale);
1309
+ const hitStrokeWidth = Math.max(strokeWidth, MIN_HIT_AREA_SCREEN_PX$6 / scale);
1306
1310
  return /* @__PURE__ */ jsxs(
1307
1311
  "svg",
1308
1312
  {
@@ -1355,7 +1359,7 @@ function Ink({
1355
1359
  }
1356
1360
  );
1357
1361
  }
1358
- const MIN_HIT_AREA_SCREEN_PX$4 = 20;
1362
+ const MIN_HIT_AREA_SCREEN_PX$5 = 20;
1359
1363
  function Square({
1360
1364
  isSelected,
1361
1365
  color = "#000000",
@@ -1395,7 +1399,7 @@ function Square({
1395
1399
  }, [isCloudy, rect, rectangleDifferences, cloudyBorderIntensity, strokeWidth]);
1396
1400
  const svgWidth = rect.size.width * scale;
1397
1401
  const svgHeight = rect.size.height * scale;
1398
- const hitStrokeWidth = Math.max(strokeWidth, MIN_HIT_AREA_SCREEN_PX$4 / scale);
1402
+ const hitStrokeWidth = Math.max(strokeWidth, MIN_HIT_AREA_SCREEN_PX$5 / scale);
1399
1403
  return /* @__PURE__ */ jsxs(
1400
1404
  "svg",
1401
1405
  {
@@ -1477,7 +1481,7 @@ function Square({
1477
1481
  }
1478
1482
  );
1479
1483
  }
1480
- const MIN_HIT_AREA_SCREEN_PX$3 = 20;
1484
+ const MIN_HIT_AREA_SCREEN_PX$4 = 20;
1481
1485
  function Circle({
1482
1486
  color = "#000000",
1483
1487
  strokeColor,
@@ -1519,7 +1523,7 @@ function Circle({
1519
1523
  }, [isCloudy, rect, rectangleDifferences, cloudyBorderIntensity, strokeWidth]);
1520
1524
  const svgWidth = width * scale;
1521
1525
  const svgHeight = height * scale;
1522
- const hitStrokeWidth = Math.max(strokeWidth, MIN_HIT_AREA_SCREEN_PX$3 / scale);
1526
+ const hitStrokeWidth = Math.max(strokeWidth, MIN_HIT_AREA_SCREEN_PX$4 / scale);
1523
1527
  return /* @__PURE__ */ jsxs(
1524
1528
  "svg",
1525
1529
  {
@@ -1601,7 +1605,7 @@ function Circle({
1601
1605
  }
1602
1606
  );
1603
1607
  }
1604
- const MIN_HIT_AREA_SCREEN_PX$2 = 20;
1608
+ const MIN_HIT_AREA_SCREEN_PX$3 = 20;
1605
1609
  function Line({
1606
1610
  color = "transparent",
1607
1611
  opacity = 1,
@@ -1634,7 +1638,7 @@ function Line({
1634
1638
  }, [lineEndings, strokeWidth, x1, y1, x2, y2]);
1635
1639
  const width = rect.size.width * scale;
1636
1640
  const height = rect.size.height * scale;
1637
- const hitStrokeWidth = Math.max(strokeWidth, MIN_HIT_AREA_SCREEN_PX$2 / scale);
1641
+ const hitStrokeWidth = Math.max(strokeWidth, MIN_HIT_AREA_SCREEN_PX$3 / scale);
1638
1642
  return /* @__PURE__ */ jsxs(
1639
1643
  "svg",
1640
1644
  {
@@ -1758,7 +1762,7 @@ function Line({
1758
1762
  }
1759
1763
  );
1760
1764
  }
1761
- const MIN_HIT_AREA_SCREEN_PX$1 = 20;
1765
+ const MIN_HIT_AREA_SCREEN_PX$2 = 20;
1762
1766
  function Polyline({
1763
1767
  rect,
1764
1768
  vertices,
@@ -1806,7 +1810,7 @@ function Polyline({
1806
1810
  }, [localPts, lineEndings, strokeWidth]);
1807
1811
  const width = rect.size.width * scale;
1808
1812
  const height = rect.size.height * scale;
1809
- const hitStrokeWidth = Math.max(strokeWidth, MIN_HIT_AREA_SCREEN_PX$1 / scale);
1813
+ const hitStrokeWidth = Math.max(strokeWidth, MIN_HIT_AREA_SCREEN_PX$2 / scale);
1810
1814
  return /* @__PURE__ */ jsxs(
1811
1815
  "svg",
1812
1816
  {
@@ -1928,7 +1932,7 @@ function Polyline({
1928
1932
  }
1929
1933
  );
1930
1934
  }
1931
- const MIN_HIT_AREA_SCREEN_PX = 20;
1935
+ const MIN_HIT_AREA_SCREEN_PX$1 = 20;
1932
1936
  function Polygon({
1933
1937
  rect,
1934
1938
  vertices,
@@ -1965,7 +1969,7 @@ function Polygon({
1965
1969
  const isPreviewing = currentVertex && vertices.length > 0;
1966
1970
  const width = rect.size.width * scale;
1967
1971
  const height = rect.size.height * scale;
1968
- const hitStrokeWidth = Math.max(strokeWidth, MIN_HIT_AREA_SCREEN_PX / scale);
1972
+ const hitStrokeWidth = Math.max(strokeWidth, MIN_HIT_AREA_SCREEN_PX$1 / scale);
1969
1973
  return /* @__PURE__ */ jsxs(
1970
1974
  "svg",
1971
1975
  {
@@ -2205,6 +2209,339 @@ function FreeText({
2205
2209
  }
2206
2210
  );
2207
2211
  }
2212
+ const MIN_HIT_AREA_SCREEN_PX = 20;
2213
+ function CalloutFreeText({
2214
+ documentId,
2215
+ isSelected,
2216
+ isEditing,
2217
+ annotation,
2218
+ pageIndex,
2219
+ scale,
2220
+ onClick,
2221
+ appearanceActive = false
2222
+ }) {
2223
+ const editorRef = useRef(null);
2224
+ const editingRef = useRef(false);
2225
+ const { provides: annotationCapability } = useAnnotationCapability();
2226
+ const annotationProvides = (annotationCapability == null ? void 0 : annotationCapability.forDocument(documentId)) ?? null;
2227
+ const obj = annotation.object;
2228
+ const rect = obj.rect;
2229
+ const rd = obj.rectangleDifferences;
2230
+ const calloutLine = obj.calloutLine;
2231
+ const strokeWidth = obj.strokeWidth ?? 1;
2232
+ const strokeColor = obj.strokeColor ?? "#000000";
2233
+ const textBox = useMemo(() => patching.computeTextBoxFromRD(rect, rd), [rect, rd]);
2234
+ const textBoxRelative = useMemo(
2235
+ () => ({
2236
+ left: (textBox.origin.x - rect.origin.x + strokeWidth / 2) * scale,
2237
+ top: (textBox.origin.y - rect.origin.y + strokeWidth / 2) * scale,
2238
+ width: (textBox.size.width - strokeWidth) * scale,
2239
+ height: (textBox.size.height - strokeWidth) * scale
2240
+ }),
2241
+ [textBox, rect, scale, strokeWidth]
2242
+ );
2243
+ const lineCoords = useMemo(() => {
2244
+ if (!calloutLine || calloutLine.length < 3) return null;
2245
+ return calloutLine.map((p) => ({
2246
+ x: p.x - rect.origin.x,
2247
+ y: p.y - rect.origin.y
2248
+ }));
2249
+ }, [calloutLine, rect]);
2250
+ const ending = useMemo(() => {
2251
+ if (!lineCoords || lineCoords.length < 2) return null;
2252
+ const angle = Math.atan2(lineCoords[1].y - lineCoords[0].y, lineCoords[1].x - lineCoords[0].x);
2253
+ return patching.createEnding(
2254
+ obj.lineEnding,
2255
+ strokeWidth,
2256
+ angle + Math.PI,
2257
+ lineCoords[0].x,
2258
+ lineCoords[0].y
2259
+ );
2260
+ }, [lineCoords, obj.lineEnding, strokeWidth]);
2261
+ const visualLineCoords = useMemo(() => {
2262
+ if (!lineCoords || lineCoords.length < 2) return lineCoords;
2263
+ const pts = lineCoords.map((p) => ({ ...p }));
2264
+ const last = pts.length - 1;
2265
+ const prev = last - 1;
2266
+ const dx = pts[last].x - pts[prev].x;
2267
+ const dy = pts[last].y - pts[prev].y;
2268
+ const len = Math.sqrt(dx * dx + dy * dy);
2269
+ if (len > 0) {
2270
+ const halfBw = strokeWidth / 2;
2271
+ pts[last].x += dx / len * halfBw;
2272
+ pts[last].y += dy / len * halfBw;
2273
+ }
2274
+ return pts;
2275
+ }, [lineCoords, strokeWidth]);
2276
+ const { adjustedFontPx, wrapperStyle } = useIOSZoomPrevention(obj.fontSize * scale, isEditing);
2277
+ useEffect(() => {
2278
+ var _a;
2279
+ if (isEditing && editorRef.current) {
2280
+ editingRef.current = true;
2281
+ const editor = editorRef.current;
2282
+ editor.focus();
2283
+ const tool = annotationProvides == null ? void 0 : annotationProvides.findToolForAnnotation(obj);
2284
+ const isDefaultContent = ((_a = tool == null ? void 0 : tool.defaults) == null ? void 0 : _a.contents) != null && obj.contents === tool.defaults.contents;
2285
+ const selection = window.getSelection();
2286
+ if (selection) {
2287
+ const range = document.createRange();
2288
+ range.selectNodeContents(editor);
2289
+ if (!isDefaultContent) {
2290
+ range.collapse(false);
2291
+ }
2292
+ selection.removeAllRanges();
2293
+ selection.addRange(range);
2294
+ }
2295
+ }
2296
+ }, [isEditing]);
2297
+ const handleBlur = () => {
2298
+ if (!editingRef.current) return;
2299
+ editingRef.current = false;
2300
+ if (!annotationProvides) return;
2301
+ if (!editorRef.current) return;
2302
+ annotationProvides.updateAnnotation(pageIndex, obj.id, {
2303
+ contents: editorRef.current.innerText.replace(/\u00A0/g, " ")
2304
+ });
2305
+ };
2306
+ const width = rect.size.width * scale;
2307
+ const height = rect.size.height * scale;
2308
+ const hitStrokeWidth = Math.max(strokeWidth, MIN_HIT_AREA_SCREEN_PX / scale);
2309
+ return /* @__PURE__ */ jsxs(
2310
+ "div",
2311
+ {
2312
+ style: {
2313
+ position: "absolute",
2314
+ width,
2315
+ height,
2316
+ cursor: isSelected && !isEditing ? "move" : "default",
2317
+ pointerEvents: "none",
2318
+ zIndex: 2,
2319
+ opacity: appearanceActive ? 0 : 1
2320
+ },
2321
+ children: [
2322
+ /* @__PURE__ */ jsxs(
2323
+ "svg",
2324
+ {
2325
+ style: {
2326
+ position: "absolute",
2327
+ width,
2328
+ height,
2329
+ pointerEvents: "none",
2330
+ overflow: "visible"
2331
+ },
2332
+ width,
2333
+ height,
2334
+ viewBox: `0 0 ${rect.size.width} ${rect.size.height}`,
2335
+ children: [
2336
+ lineCoords && /* @__PURE__ */ jsxs(Fragment, { children: [
2337
+ /* @__PURE__ */ jsx(
2338
+ "polyline",
2339
+ {
2340
+ points: lineCoords.map((p) => `${p.x},${p.y}`).join(" "),
2341
+ fill: "none",
2342
+ stroke: "transparent",
2343
+ strokeWidth: hitStrokeWidth,
2344
+ onPointerDown: onClick ? (e) => onClick(e) : void 0,
2345
+ style: {
2346
+ cursor: isSelected ? "move" : onClick ? "pointer" : "default",
2347
+ pointerEvents: !onClick ? "none" : isSelected ? "none" : "visibleStroke"
2348
+ }
2349
+ }
2350
+ ),
2351
+ ending && /* @__PURE__ */ jsx(
2352
+ "path",
2353
+ {
2354
+ d: ending.d,
2355
+ transform: ending.transform,
2356
+ fill: "transparent",
2357
+ stroke: "transparent",
2358
+ strokeWidth: hitStrokeWidth,
2359
+ onPointerDown: onClick ? (e) => onClick(e) : void 0,
2360
+ style: {
2361
+ cursor: isSelected ? "move" : onClick ? "pointer" : "default",
2362
+ pointerEvents: !onClick ? "none" : isSelected ? "none" : ending.filled ? "visible" : "visibleStroke"
2363
+ }
2364
+ }
2365
+ )
2366
+ ] }),
2367
+ !appearanceActive && /* @__PURE__ */ jsxs(Fragment, { children: [
2368
+ visualLineCoords && /* @__PURE__ */ jsxs(Fragment, { children: [
2369
+ /* @__PURE__ */ jsx(
2370
+ "polyline",
2371
+ {
2372
+ points: visualLineCoords.map((p) => `${p.x},${p.y}`).join(" "),
2373
+ fill: "none",
2374
+ stroke: strokeColor,
2375
+ strokeWidth,
2376
+ opacity: obj.opacity,
2377
+ style: { pointerEvents: "none" }
2378
+ }
2379
+ ),
2380
+ ending && /* @__PURE__ */ jsx(
2381
+ "path",
2382
+ {
2383
+ d: ending.d,
2384
+ transform: ending.transform,
2385
+ stroke: strokeColor,
2386
+ fill: ending.filled ? obj.color ?? "transparent" : "none",
2387
+ strokeWidth,
2388
+ opacity: obj.opacity,
2389
+ style: { pointerEvents: "none" }
2390
+ }
2391
+ )
2392
+ ] }),
2393
+ /* @__PURE__ */ jsx(
2394
+ "rect",
2395
+ {
2396
+ x: textBox.origin.x - rect.origin.x + strokeWidth / 2,
2397
+ y: textBox.origin.y - rect.origin.y + strokeWidth / 2,
2398
+ width: textBox.size.width - strokeWidth,
2399
+ height: textBox.size.height - strokeWidth,
2400
+ fill: obj.color ?? obj.backgroundColor ?? "transparent",
2401
+ stroke: strokeColor,
2402
+ strokeWidth,
2403
+ opacity: obj.opacity,
2404
+ style: { pointerEvents: "none" }
2405
+ }
2406
+ )
2407
+ ] })
2408
+ ]
2409
+ }
2410
+ ),
2411
+ /* @__PURE__ */ jsx(
2412
+ "div",
2413
+ {
2414
+ onPointerDown: onClick ? (e) => onClick(e) : void 0,
2415
+ style: {
2416
+ position: "absolute",
2417
+ left: (textBox.origin.x - rect.origin.x) * scale,
2418
+ top: (textBox.origin.y - rect.origin.y) * scale,
2419
+ width: textBox.size.width * scale,
2420
+ height: textBox.size.height * scale,
2421
+ cursor: isSelected && !isEditing ? "move" : onClick ? "pointer" : "default",
2422
+ pointerEvents: !onClick ? "none" : isSelected && !isEditing ? "none" : "auto"
2423
+ }
2424
+ }
2425
+ ),
2426
+ /* @__PURE__ */ jsx(
2427
+ "span",
2428
+ {
2429
+ ref: editorRef,
2430
+ onBlur: handleBlur,
2431
+ tabIndex: 0,
2432
+ style: {
2433
+ position: "absolute",
2434
+ left: textBoxRelative.left,
2435
+ top: textBoxRelative.top,
2436
+ width: textBoxRelative.width,
2437
+ height: textBoxRelative.height,
2438
+ color: obj.fontColor,
2439
+ fontSize: adjustedFontPx,
2440
+ ...standardFontCssProperties(obj.fontFamily),
2441
+ textAlign: textAlignmentToCss(obj.textAlign),
2442
+ flexDirection: "column",
2443
+ justifyContent: obj.verticalAlign === PdfVerticalAlignment.Top ? "flex-start" : obj.verticalAlign === PdfVerticalAlignment.Middle ? "center" : "flex-end",
2444
+ display: "flex",
2445
+ padding: strokeWidth * scale / 2 + 2 * scale,
2446
+ opacity: obj.opacity,
2447
+ lineHeight: "1.18",
2448
+ overflow: "hidden",
2449
+ cursor: isEditing ? "text" : "default",
2450
+ outline: "none",
2451
+ pointerEvents: isEditing ? "auto" : "none",
2452
+ ...wrapperStyle
2453
+ },
2454
+ contentEditable: isEditing,
2455
+ ...suppressContentEditableWarningProps,
2456
+ children: obj.contents
2457
+ }
2458
+ )
2459
+ ]
2460
+ }
2461
+ );
2462
+ }
2463
+ function CalloutFreeTextPreview({
2464
+ calloutLine,
2465
+ textBox,
2466
+ bounds,
2467
+ scale,
2468
+ strokeColor,
2469
+ strokeWidth,
2470
+ color,
2471
+ backgroundColor,
2472
+ opacity,
2473
+ lineEnding
2474
+ }) {
2475
+ if (!calloutLine || calloutLine.length < 2) return /* @__PURE__ */ jsx(Fragment$1, {});
2476
+ const sw = strokeWidth ?? 1;
2477
+ const sc = strokeColor ?? "#000000";
2478
+ const op = opacity ?? 1;
2479
+ const w = bounds.size.width;
2480
+ const h = bounds.size.height;
2481
+ const ox = bounds.origin.x;
2482
+ const oy = bounds.origin.y;
2483
+ const lineCoords = calloutLine.map((p) => ({ x: p.x - ox, y: p.y - oy }));
2484
+ const angle = Math.atan2(lineCoords[1].y - lineCoords[0].y, lineCoords[1].x - lineCoords[0].x);
2485
+ const ending = patching.createEnding(
2486
+ lineEnding,
2487
+ sw,
2488
+ angle + Math.PI,
2489
+ lineCoords[0].x,
2490
+ lineCoords[0].y
2491
+ );
2492
+ const halfSw = sw / 2;
2493
+ return /* @__PURE__ */ jsxs(
2494
+ "svg",
2495
+ {
2496
+ style: {
2497
+ position: "absolute",
2498
+ width: w * scale,
2499
+ height: h * scale,
2500
+ pointerEvents: "none",
2501
+ overflow: "visible"
2502
+ },
2503
+ width: w * scale,
2504
+ height: h * scale,
2505
+ viewBox: `0 0 ${w} ${h}`,
2506
+ children: [
2507
+ /* @__PURE__ */ jsx(
2508
+ "polyline",
2509
+ {
2510
+ points: lineCoords.map((p) => `${p.x},${p.y}`).join(" "),
2511
+ fill: "none",
2512
+ stroke: sc,
2513
+ strokeWidth: sw,
2514
+ opacity: op
2515
+ }
2516
+ ),
2517
+ ending && /* @__PURE__ */ jsx(
2518
+ "path",
2519
+ {
2520
+ d: ending.d,
2521
+ transform: ending.transform,
2522
+ stroke: sc,
2523
+ fill: ending.filled ? color ?? "transparent" : "none",
2524
+ strokeWidth: sw,
2525
+ opacity: op
2526
+ }
2527
+ ),
2528
+ textBox && /* @__PURE__ */ jsx(
2529
+ "rect",
2530
+ {
2531
+ x: textBox.origin.x - ox + halfSw,
2532
+ y: textBox.origin.y - oy + halfSw,
2533
+ width: textBox.size.width - sw,
2534
+ height: textBox.size.height - sw,
2535
+ fill: color ?? backgroundColor ?? "transparent",
2536
+ stroke: sc,
2537
+ strokeWidth: sw,
2538
+ opacity: op
2539
+ }
2540
+ )
2541
+ ]
2542
+ }
2543
+ );
2544
+ }
2208
2545
  function RenderAnnotation({
2209
2546
  documentId,
2210
2547
  pageIndex,
@@ -2897,11 +3234,59 @@ const builtInRenderers = [
2897
3234
  ),
2898
3235
  interactionDefaults: { isDraggable: false, isResizable: false, isRotatable: false }
2899
3236
  }),
3237
+ // --- Callout FreeText (must appear before regular FreeText to match first) ---
3238
+ createRenderer({
3239
+ id: "freeTextCallout",
3240
+ matches: (a) => a.type === PdfAnnotationSubtype.FREETEXT && a.intent === "FreeTextCallout",
3241
+ matchesPreview: (p) => p.type === PdfAnnotationSubtype.FREETEXT && !!p.data.calloutLine,
3242
+ render: ({
3243
+ annotation,
3244
+ currentObject,
3245
+ isSelected,
3246
+ isEditing,
3247
+ scale,
3248
+ pageIndex,
3249
+ documentId,
3250
+ onClick,
3251
+ appearanceActive
3252
+ }) => /* @__PURE__ */ jsx(
3253
+ CalloutFreeText,
3254
+ {
3255
+ documentId,
3256
+ isSelected,
3257
+ isEditing,
3258
+ annotation: { ...annotation, object: currentObject },
3259
+ pageIndex,
3260
+ scale,
3261
+ onClick,
3262
+ appearanceActive
3263
+ }
3264
+ ),
3265
+ renderPreview: ({ data, bounds, scale }) => /* @__PURE__ */ jsx(
3266
+ CalloutFreeTextPreview,
3267
+ {
3268
+ calloutLine: data.calloutLine,
3269
+ textBox: data.textBox,
3270
+ bounds,
3271
+ scale,
3272
+ strokeColor: data.strokeColor,
3273
+ strokeWidth: data.strokeWidth,
3274
+ color: data.color,
3275
+ backgroundColor: data.backgroundColor,
3276
+ opacity: data.opacity,
3277
+ lineEnding: data.lineEnding
3278
+ }
3279
+ ),
3280
+ vertexConfig: patching.calloutVertexConfig,
3281
+ interactionDefaults: { isDraggable: true, isResizable: false, isRotatable: false },
3282
+ isDraggable: (toolDraggable, { isEditing }) => toolDraggable && !isEditing,
3283
+ onDoubleClick: (id, setEditingId) => setEditingId(id)
3284
+ }),
2900
3285
  // --- FreeText ---
2901
3286
  createRenderer({
2902
3287
  id: "freeText",
2903
- matches: (a) => a.type === PdfAnnotationSubtype.FREETEXT,
2904
- matchesPreview: (p) => p.type === PdfAnnotationSubtype.FREETEXT,
3288
+ matches: (a) => a.type === PdfAnnotationSubtype.FREETEXT && a.intent !== "FreeTextCallout",
3289
+ matchesPreview: (p) => p.type === PdfAnnotationSubtype.FREETEXT && !p.data.calloutLine,
2905
3290
  render: ({
2906
3291
  annotation,
2907
3292
  currentObject,
@@ -3040,7 +3425,7 @@ function Annotations(annotationsProps) {
3040
3425
  const [allSelectedIds, setAllSelectedIds] = useState([]);
3041
3426
  const [editingId, setEditingId] = useState(null);
3042
3427
  const [appearanceMap, setAppearanceMap] = useState({});
3043
- const [lockedMode, setLockedMode] = useState({ type: LockModeType.None });
3428
+ const [, setLockedMode] = useState({ type: LockModeType.None });
3044
3429
  const prevScaleRef = useRef(scale);
3045
3430
  const annotationProvides = useMemo(
3046
3431
  () => annotationCapability ? annotationCapability.forDocument(documentId) : null,
@@ -3230,35 +3615,38 @@ function Annotations(annotationsProps) {
3230
3615
  var _a, _b, _c;
3231
3616
  const renderer = resolveRenderer(annotation);
3232
3617
  if (!renderer) return null;
3618
+ if (hasNoViewFlag(annotation.object)) return null;
3619
+ if (hasHiddenFlag(annotation.object)) return null;
3233
3620
  const tool = (annotationProvides == null ? void 0 : annotationProvides.findToolForAnnotation(annotation.object)) ?? null;
3234
- const categories = getAnnotationCategories(tool);
3235
- const locked = hasLockedFlag(annotation.object) || isCategoryLocked(categories, lockedMode);
3236
- if (locked && renderer.hiddenWhenLocked) return null;
3237
- const hasRenderLocked = locked && !!renderer.renderLocked;
3238
- const isSelected = locked ? false : allSelectedIds.includes(annotation.object.id);
3239
- const isEditing = locked ? false : editingId === annotation.object.id;
3621
+ const nonInteractive = annotationProvides ? !annotationProvides.isAnnotationInteractive(annotation.object) : false;
3622
+ const structurallyLocked = annotationProvides ? annotationProvides.isAnnotationStructurallyLocked(annotation.object) : false;
3623
+ const contentLocked = annotationProvides ? annotationProvides.isAnnotationContentLocked(annotation.object) : false;
3624
+ if (nonInteractive && renderer.hiddenWhenLocked) return null;
3625
+ const hasRenderLocked = nonInteractive && !!renderer.renderLocked;
3626
+ const isSelected = nonInteractive ? false : allSelectedIds.includes(annotation.object.id);
3627
+ const isEditing = nonInteractive ? false : editingId === annotation.object.id;
3240
3628
  const defaults = renderer.interactionDefaults;
3241
3629
  const resolvedDraggable = resolveInteractionProp(
3242
3630
  tool == null ? void 0 : tool.interaction.isDraggable,
3243
3631
  annotation.object,
3244
3632
  (defaults == null ? void 0 : defaults.isDraggable) ?? true
3245
3633
  );
3246
- const finalDraggable = locked ? false : renderer.isDraggable ? renderer.isDraggable(resolvedDraggable, { isEditing }) : resolvedDraggable;
3634
+ const finalDraggable = structurallyLocked ? false : renderer.isDraggable ? renderer.isDraggable(resolvedDraggable, { isEditing }) : resolvedDraggable;
3247
3635
  const useAP = ((_a = tool == null ? void 0 : tool.behavior) == null ? void 0 : _a.useAppearanceStream) ?? renderer.useAppearanceStream ?? true;
3248
3636
  const appearance = hasRenderLocked ? void 0 : useAP ? getAppearanceForAnnotation(annotation) : void 0;
3249
3637
  const noopSelect = (e) => {
3250
3638
  e.stopPropagation();
3251
3639
  };
3252
- const onSelect = locked ? noopSelect : renderer.selectOverride ? (e) => renderer.selectOverride(e, annotation, selectHelpers) : (e) => handleClick(e, annotation);
3640
+ const onSelect = nonInteractive ? noopSelect : renderer.selectOverride ? (e) => renderer.selectOverride(e, annotation, selectHelpers) : (e) => handleClick(e, annotation);
3253
3641
  return /* @__PURE__ */ jsx(
3254
3642
  AnnotationContainer,
3255
3643
  {
3256
3644
  trackedAnnotation: annotation,
3257
3645
  isSelected,
3258
3646
  isEditing,
3259
- isMultiSelected: locked ? false : isMultiSelected,
3647
+ isMultiSelected: nonInteractive ? false : isMultiSelected,
3260
3648
  isDraggable: finalDraggable,
3261
- isResizable: locked ? false : resolveInteractionProp(
3649
+ isResizable: structurallyLocked ? false : resolveInteractionProp(
3262
3650
  tool == null ? void 0 : tool.interaction.isResizable,
3263
3651
  annotation.object,
3264
3652
  (defaults == null ? void 0 : defaults.isResizable) ?? false
@@ -3268,15 +3656,17 @@ function Annotations(annotationsProps) {
3268
3656
  annotation.object,
3269
3657
  (defaults == null ? void 0 : defaults.lockAspectRatio) ?? false
3270
3658
  ),
3271
- isRotatable: locked ? false : resolveInteractionProp(
3659
+ isRotatable: structurallyLocked ? false : resolveInteractionProp(
3272
3660
  tool == null ? void 0 : tool.interaction.isRotatable,
3273
3661
  annotation.object,
3274
3662
  (defaults == null ? void 0 : defaults.isRotatable) ?? false
3275
3663
  ),
3276
- vertexConfig: locked ? void 0 : renderer.vertexConfig,
3277
- selectionMenu: locked ? void 0 : ((_b = renderer.hideSelectionMenu) == null ? void 0 : _b.call(renderer, annotation.object)) ? void 0 : selectionMenu,
3664
+ vertexConfig: structurallyLocked ? void 0 : renderer.vertexConfig,
3665
+ selectionMenu: nonInteractive ? void 0 : ((_b = renderer.hideSelectionMenu) == null ? void 0 : _b.call(renderer, annotation.object)) ? void 0 : selectionMenu,
3666
+ structurallyLocked,
3667
+ contentLocked,
3278
3668
  onSelect,
3279
- onDoubleClick: locked ? void 0 : renderer.onDoubleClick ? (e) => {
3669
+ onDoubleClick: nonInteractive || contentLocked ? void 0 : renderer.onDoubleClick ? (e) => {
3280
3670
  e.stopPropagation();
3281
3671
  renderer.onDoubleClick(annotation.object.id, setEditingId);
3282
3672
  } : void 0,
@@ -3309,7 +3699,7 @@ function Annotations(annotationsProps) {
3309
3699
  scale,
3310
3700
  pageIndex,
3311
3701
  documentId,
3312
- onClick: locked ? void 0 : onSelect,
3702
+ onClick: nonInteractive ? void 0 : onSelect,
3313
3703
  appearanceActive
3314
3704
  });
3315
3705
  }