@embedpdf/plugin-annotation 2.13.0 → 2.14.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (40) hide show
  1. package/dist/index.cjs +1 -1
  2. package/dist/index.cjs.map +1 -1
  3. package/dist/index.js +449 -1
  4. package/dist/index.js.map +1 -1
  5. package/dist/lib/handlers/callout-free-text.handler.d.ts +3 -0
  6. package/dist/lib/handlers/index.d.ts +1 -0
  7. package/dist/lib/handlers/types.d.ts +7 -1
  8. package/dist/lib/patching/patch-utils.d.ts +38 -1
  9. package/dist/lib/patching/patches/callout-freetext.patch.d.ts +3 -0
  10. package/dist/lib/patching/patches/index.d.ts +1 -0
  11. package/dist/lib/tools/default-tools.d.ts +35 -0
  12. package/dist/preact/index.cjs +1 -1
  13. package/dist/preact/index.cjs.map +1 -1
  14. package/dist/preact/index.js +395 -14
  15. package/dist/preact/index.js.map +1 -1
  16. package/dist/react/index.cjs +1 -1
  17. package/dist/react/index.cjs.map +1 -1
  18. package/dist/react/index.js +395 -14
  19. package/dist/react/index.js.map +1 -1
  20. package/dist/shared/components/annotations/callout-free-text-preview.d.ts +15 -0
  21. package/dist/shared/components/annotations/callout-free-text.d.ts +15 -0
  22. package/dist/shared-preact/components/annotations/callout-free-text-preview.d.ts +15 -0
  23. package/dist/shared-preact/components/annotations/callout-free-text.d.ts +15 -0
  24. package/dist/shared-react/components/annotations/callout-free-text-preview.d.ts +15 -0
  25. package/dist/shared-react/components/annotations/callout-free-text.d.ts +15 -0
  26. package/dist/svelte/components/annotations/CalloutFreeText.svelte.d.ts +15 -0
  27. package/dist/svelte/components/annotations/CalloutFreeTextPreview.svelte.d.ts +10 -0
  28. package/dist/svelte/components/renderers/CalloutFreeTextRenderer.svelte.d.ts +5 -0
  29. package/dist/svelte/index.cjs +1 -1
  30. package/dist/svelte/index.cjs.map +1 -1
  31. package/dist/svelte/index.js +497 -86
  32. package/dist/svelte/index.js.map +1 -1
  33. package/dist/vue/components/annotations/callout-free-text-preview.vue.d.ts +10 -0
  34. package/dist/vue/components/annotations/callout-free-text.vue.d.ts +25 -0
  35. package/dist/vue/components/renderers/callout-free-text-renderer.vue.d.ts +6 -0
  36. package/dist/vue/index.cjs +1 -1
  37. package/dist/vue/index.cjs.map +1 -1
  38. package/dist/vue/index.js +544 -170
  39. package/dist/vue/index.js.map +1 -1
  40. package/package.json +12 -12
@@ -1275,7 +1275,7 @@ function createRenderer(entry) {
1275
1275
  renderLocked: entry.renderLocked ? (props) => entry.renderLocked(props) : void 0
1276
1276
  };
1277
1277
  }
1278
- const MIN_HIT_AREA_SCREEN_PX$5 = 20;
1278
+ const MIN_HIT_AREA_SCREEN_PX$6 = 20;
1279
1279
  function Ink({
1280
1280
  isSelected,
1281
1281
  strokeColor,
@@ -1301,7 +1301,7 @@ function Ink({
1301
1301
  }, [inkList, rect]);
1302
1302
  const width = rect.size.width * scale;
1303
1303
  const height = rect.size.height * scale;
1304
- const hitStrokeWidth = Math.max(strokeWidth, MIN_HIT_AREA_SCREEN_PX$5 / scale);
1304
+ const hitStrokeWidth = Math.max(strokeWidth, MIN_HIT_AREA_SCREEN_PX$6 / scale);
1305
1305
  return /* @__PURE__ */ jsxs(
1306
1306
  "svg",
1307
1307
  {
@@ -1354,7 +1354,7 @@ function Ink({
1354
1354
  }
1355
1355
  );
1356
1356
  }
1357
- const MIN_HIT_AREA_SCREEN_PX$4 = 20;
1357
+ const MIN_HIT_AREA_SCREEN_PX$5 = 20;
1358
1358
  function Square({
1359
1359
  isSelected,
1360
1360
  color = "#000000",
@@ -1394,7 +1394,7 @@ function Square({
1394
1394
  }, [isCloudy, rect, rectangleDifferences, cloudyBorderIntensity, strokeWidth]);
1395
1395
  const svgWidth = rect.size.width * scale;
1396
1396
  const svgHeight = rect.size.height * scale;
1397
- const hitStrokeWidth = Math.max(strokeWidth, MIN_HIT_AREA_SCREEN_PX$4 / scale);
1397
+ const hitStrokeWidth = Math.max(strokeWidth, MIN_HIT_AREA_SCREEN_PX$5 / scale);
1398
1398
  return /* @__PURE__ */ jsxs(
1399
1399
  "svg",
1400
1400
  {
@@ -1476,7 +1476,7 @@ function Square({
1476
1476
  }
1477
1477
  );
1478
1478
  }
1479
- const MIN_HIT_AREA_SCREEN_PX$3 = 20;
1479
+ const MIN_HIT_AREA_SCREEN_PX$4 = 20;
1480
1480
  function Circle({
1481
1481
  color = "#000000",
1482
1482
  strokeColor,
@@ -1518,7 +1518,7 @@ function Circle({
1518
1518
  }, [isCloudy, rect, rectangleDifferences, cloudyBorderIntensity, strokeWidth]);
1519
1519
  const svgWidth = width * scale;
1520
1520
  const svgHeight = height * scale;
1521
- const hitStrokeWidth = Math.max(strokeWidth, MIN_HIT_AREA_SCREEN_PX$3 / scale);
1521
+ const hitStrokeWidth = Math.max(strokeWidth, MIN_HIT_AREA_SCREEN_PX$4 / scale);
1522
1522
  return /* @__PURE__ */ jsxs(
1523
1523
  "svg",
1524
1524
  {
@@ -1600,7 +1600,7 @@ function Circle({
1600
1600
  }
1601
1601
  );
1602
1602
  }
1603
- const MIN_HIT_AREA_SCREEN_PX$2 = 20;
1603
+ const MIN_HIT_AREA_SCREEN_PX$3 = 20;
1604
1604
  function Line({
1605
1605
  color = "transparent",
1606
1606
  opacity = 1,
@@ -1633,7 +1633,7 @@ function Line({
1633
1633
  }, [lineEndings, strokeWidth, x1, y1, x2, y2]);
1634
1634
  const width = rect.size.width * scale;
1635
1635
  const height = rect.size.height * scale;
1636
- const hitStrokeWidth = Math.max(strokeWidth, MIN_HIT_AREA_SCREEN_PX$2 / scale);
1636
+ const hitStrokeWidth = Math.max(strokeWidth, MIN_HIT_AREA_SCREEN_PX$3 / scale);
1637
1637
  return /* @__PURE__ */ jsxs(
1638
1638
  "svg",
1639
1639
  {
@@ -1757,7 +1757,7 @@ function Line({
1757
1757
  }
1758
1758
  );
1759
1759
  }
1760
- const MIN_HIT_AREA_SCREEN_PX$1 = 20;
1760
+ const MIN_HIT_AREA_SCREEN_PX$2 = 20;
1761
1761
  function Polyline({
1762
1762
  rect,
1763
1763
  vertices,
@@ -1805,7 +1805,7 @@ function Polyline({
1805
1805
  }, [localPts, lineEndings, strokeWidth]);
1806
1806
  const width = rect.size.width * scale;
1807
1807
  const height = rect.size.height * scale;
1808
- const hitStrokeWidth = Math.max(strokeWidth, MIN_HIT_AREA_SCREEN_PX$1 / scale);
1808
+ const hitStrokeWidth = Math.max(strokeWidth, MIN_HIT_AREA_SCREEN_PX$2 / scale);
1809
1809
  return /* @__PURE__ */ jsxs(
1810
1810
  "svg",
1811
1811
  {
@@ -1927,7 +1927,7 @@ function Polyline({
1927
1927
  }
1928
1928
  );
1929
1929
  }
1930
- const MIN_HIT_AREA_SCREEN_PX = 20;
1930
+ const MIN_HIT_AREA_SCREEN_PX$1 = 20;
1931
1931
  function Polygon({
1932
1932
  rect,
1933
1933
  vertices,
@@ -1964,7 +1964,7 @@ function Polygon({
1964
1964
  const isPreviewing = currentVertex && vertices.length > 0;
1965
1965
  const width = rect.size.width * scale;
1966
1966
  const height = rect.size.height * scale;
1967
- const hitStrokeWidth = Math.max(strokeWidth, MIN_HIT_AREA_SCREEN_PX / scale);
1967
+ const hitStrokeWidth = Math.max(strokeWidth, MIN_HIT_AREA_SCREEN_PX$1 / scale);
1968
1968
  return /* @__PURE__ */ jsxs(
1969
1969
  "svg",
1970
1970
  {
@@ -2204,6 +2204,339 @@ function FreeText({
2204
2204
  }
2205
2205
  );
2206
2206
  }
2207
+ const MIN_HIT_AREA_SCREEN_PX = 20;
2208
+ function CalloutFreeText({
2209
+ documentId,
2210
+ isSelected,
2211
+ isEditing,
2212
+ annotation,
2213
+ pageIndex,
2214
+ scale,
2215
+ onClick,
2216
+ appearanceActive = false
2217
+ }) {
2218
+ const editorRef = useRef(null);
2219
+ const editingRef = useRef(false);
2220
+ const { provides: annotationCapability } = useAnnotationCapability();
2221
+ const annotationProvides = (annotationCapability == null ? void 0 : annotationCapability.forDocument(documentId)) ?? null;
2222
+ const obj = annotation.object;
2223
+ const rect = obj.rect;
2224
+ const rd = obj.rectangleDifferences;
2225
+ const calloutLine = obj.calloutLine;
2226
+ const strokeWidth = obj.strokeWidth ?? 1;
2227
+ const strokeColor = obj.strokeColor ?? "#000000";
2228
+ const textBox = useMemo(() => patching.computeTextBoxFromRD(rect, rd), [rect, rd]);
2229
+ const textBoxRelative = useMemo(
2230
+ () => ({
2231
+ left: (textBox.origin.x - rect.origin.x + strokeWidth / 2) * scale,
2232
+ top: (textBox.origin.y - rect.origin.y + strokeWidth / 2) * scale,
2233
+ width: (textBox.size.width - strokeWidth) * scale,
2234
+ height: (textBox.size.height - strokeWidth) * scale
2235
+ }),
2236
+ [textBox, rect, scale, strokeWidth]
2237
+ );
2238
+ const lineCoords = useMemo(() => {
2239
+ if (!calloutLine || calloutLine.length < 3) return null;
2240
+ return calloutLine.map((p) => ({
2241
+ x: p.x - rect.origin.x,
2242
+ y: p.y - rect.origin.y
2243
+ }));
2244
+ }, [calloutLine, rect]);
2245
+ const ending = useMemo(() => {
2246
+ if (!lineCoords || lineCoords.length < 2) return null;
2247
+ const angle = Math.atan2(lineCoords[1].y - lineCoords[0].y, lineCoords[1].x - lineCoords[0].x);
2248
+ return patching.createEnding(
2249
+ obj.lineEnding,
2250
+ strokeWidth,
2251
+ angle + Math.PI,
2252
+ lineCoords[0].x,
2253
+ lineCoords[0].y
2254
+ );
2255
+ }, [lineCoords, obj.lineEnding, strokeWidth]);
2256
+ const visualLineCoords = useMemo(() => {
2257
+ if (!lineCoords || lineCoords.length < 2) return lineCoords;
2258
+ const pts = lineCoords.map((p) => ({ ...p }));
2259
+ const last = pts.length - 1;
2260
+ const prev = last - 1;
2261
+ const dx = pts[last].x - pts[prev].x;
2262
+ const dy = pts[last].y - pts[prev].y;
2263
+ const len = Math.sqrt(dx * dx + dy * dy);
2264
+ if (len > 0) {
2265
+ const halfBw = strokeWidth / 2;
2266
+ pts[last].x += dx / len * halfBw;
2267
+ pts[last].y += dy / len * halfBw;
2268
+ }
2269
+ return pts;
2270
+ }, [lineCoords, strokeWidth]);
2271
+ const { adjustedFontPx, wrapperStyle } = useIOSZoomPrevention(obj.fontSize * scale, isEditing);
2272
+ useEffect(() => {
2273
+ var _a;
2274
+ if (isEditing && editorRef.current) {
2275
+ editingRef.current = true;
2276
+ const editor = editorRef.current;
2277
+ editor.focus();
2278
+ const tool = annotationProvides == null ? void 0 : annotationProvides.findToolForAnnotation(obj);
2279
+ const isDefaultContent = ((_a = tool == null ? void 0 : tool.defaults) == null ? void 0 : _a.contents) != null && obj.contents === tool.defaults.contents;
2280
+ const selection = window.getSelection();
2281
+ if (selection) {
2282
+ const range = document.createRange();
2283
+ range.selectNodeContents(editor);
2284
+ if (!isDefaultContent) {
2285
+ range.collapse(false);
2286
+ }
2287
+ selection.removeAllRanges();
2288
+ selection.addRange(range);
2289
+ }
2290
+ }
2291
+ }, [isEditing]);
2292
+ const handleBlur = () => {
2293
+ if (!editingRef.current) return;
2294
+ editingRef.current = false;
2295
+ if (!annotationProvides) return;
2296
+ if (!editorRef.current) return;
2297
+ annotationProvides.updateAnnotation(pageIndex, obj.id, {
2298
+ contents: editorRef.current.innerText.replace(/\u00A0/g, " ")
2299
+ });
2300
+ };
2301
+ const width = rect.size.width * scale;
2302
+ const height = rect.size.height * scale;
2303
+ const hitStrokeWidth = Math.max(strokeWidth, MIN_HIT_AREA_SCREEN_PX / scale);
2304
+ return /* @__PURE__ */ jsxs(
2305
+ "div",
2306
+ {
2307
+ style: {
2308
+ position: "absolute",
2309
+ width,
2310
+ height,
2311
+ cursor: isSelected && !isEditing ? "move" : "default",
2312
+ pointerEvents: "none",
2313
+ zIndex: 2,
2314
+ opacity: appearanceActive ? 0 : 1
2315
+ },
2316
+ children: [
2317
+ /* @__PURE__ */ jsxs(
2318
+ "svg",
2319
+ {
2320
+ style: {
2321
+ position: "absolute",
2322
+ width,
2323
+ height,
2324
+ pointerEvents: "none",
2325
+ overflow: "visible"
2326
+ },
2327
+ width,
2328
+ height,
2329
+ viewBox: `0 0 ${rect.size.width} ${rect.size.height}`,
2330
+ children: [
2331
+ lineCoords && /* @__PURE__ */ jsxs(Fragment, { children: [
2332
+ /* @__PURE__ */ jsx(
2333
+ "polyline",
2334
+ {
2335
+ points: lineCoords.map((p) => `${p.x},${p.y}`).join(" "),
2336
+ fill: "none",
2337
+ stroke: "transparent",
2338
+ strokeWidth: hitStrokeWidth,
2339
+ onPointerDown: onClick ? (e) => onClick(e) : void 0,
2340
+ style: {
2341
+ cursor: isSelected ? "move" : onClick ? "pointer" : "default",
2342
+ pointerEvents: !onClick ? "none" : isSelected ? "none" : "visibleStroke"
2343
+ }
2344
+ }
2345
+ ),
2346
+ ending && /* @__PURE__ */ jsx(
2347
+ "path",
2348
+ {
2349
+ d: ending.d,
2350
+ transform: ending.transform,
2351
+ fill: "transparent",
2352
+ stroke: "transparent",
2353
+ strokeWidth: hitStrokeWidth,
2354
+ onPointerDown: onClick ? (e) => onClick(e) : void 0,
2355
+ style: {
2356
+ cursor: isSelected ? "move" : onClick ? "pointer" : "default",
2357
+ pointerEvents: !onClick ? "none" : isSelected ? "none" : ending.filled ? "visible" : "visibleStroke"
2358
+ }
2359
+ }
2360
+ )
2361
+ ] }),
2362
+ !appearanceActive && /* @__PURE__ */ jsxs(Fragment, { children: [
2363
+ visualLineCoords && /* @__PURE__ */ jsxs(Fragment, { children: [
2364
+ /* @__PURE__ */ jsx(
2365
+ "polyline",
2366
+ {
2367
+ points: visualLineCoords.map((p) => `${p.x},${p.y}`).join(" "),
2368
+ fill: "none",
2369
+ stroke: strokeColor,
2370
+ strokeWidth,
2371
+ opacity: obj.opacity,
2372
+ style: { pointerEvents: "none" }
2373
+ }
2374
+ ),
2375
+ ending && /* @__PURE__ */ jsx(
2376
+ "path",
2377
+ {
2378
+ d: ending.d,
2379
+ transform: ending.transform,
2380
+ stroke: strokeColor,
2381
+ fill: ending.filled ? obj.color ?? "transparent" : "none",
2382
+ strokeWidth,
2383
+ opacity: obj.opacity,
2384
+ style: { pointerEvents: "none" }
2385
+ }
2386
+ )
2387
+ ] }),
2388
+ /* @__PURE__ */ jsx(
2389
+ "rect",
2390
+ {
2391
+ x: textBox.origin.x - rect.origin.x + strokeWidth / 2,
2392
+ y: textBox.origin.y - rect.origin.y + strokeWidth / 2,
2393
+ width: textBox.size.width - strokeWidth,
2394
+ height: textBox.size.height - strokeWidth,
2395
+ fill: obj.color ?? obj.backgroundColor ?? "transparent",
2396
+ stroke: strokeColor,
2397
+ strokeWidth,
2398
+ opacity: obj.opacity,
2399
+ style: { pointerEvents: "none" }
2400
+ }
2401
+ )
2402
+ ] })
2403
+ ]
2404
+ }
2405
+ ),
2406
+ /* @__PURE__ */ jsx(
2407
+ "div",
2408
+ {
2409
+ onPointerDown: onClick ? (e) => onClick(e) : void 0,
2410
+ style: {
2411
+ position: "absolute",
2412
+ left: (textBox.origin.x - rect.origin.x) * scale,
2413
+ top: (textBox.origin.y - rect.origin.y) * scale,
2414
+ width: textBox.size.width * scale,
2415
+ height: textBox.size.height * scale,
2416
+ cursor: isSelected && !isEditing ? "move" : onClick ? "pointer" : "default",
2417
+ pointerEvents: !onClick ? "none" : isSelected && !isEditing ? "none" : "auto"
2418
+ }
2419
+ }
2420
+ ),
2421
+ /* @__PURE__ */ jsx(
2422
+ "span",
2423
+ {
2424
+ ref: editorRef,
2425
+ onBlur: handleBlur,
2426
+ tabIndex: 0,
2427
+ style: {
2428
+ position: "absolute",
2429
+ left: textBoxRelative.left,
2430
+ top: textBoxRelative.top,
2431
+ width: textBoxRelative.width,
2432
+ height: textBoxRelative.height,
2433
+ color: obj.fontColor,
2434
+ fontSize: adjustedFontPx,
2435
+ ...standardFontCssProperties(obj.fontFamily),
2436
+ textAlign: textAlignmentToCss(obj.textAlign),
2437
+ flexDirection: "column",
2438
+ justifyContent: obj.verticalAlign === PdfVerticalAlignment.Top ? "flex-start" : obj.verticalAlign === PdfVerticalAlignment.Middle ? "center" : "flex-end",
2439
+ display: "flex",
2440
+ padding: strokeWidth * scale / 2 + 2 * scale,
2441
+ opacity: obj.opacity,
2442
+ lineHeight: "1.18",
2443
+ overflow: "hidden",
2444
+ cursor: isEditing ? "text" : "default",
2445
+ outline: "none",
2446
+ pointerEvents: isEditing ? "auto" : "none",
2447
+ ...wrapperStyle
2448
+ },
2449
+ contentEditable: isEditing,
2450
+ ...suppressContentEditableWarningProps,
2451
+ children: obj.contents
2452
+ }
2453
+ )
2454
+ ]
2455
+ }
2456
+ );
2457
+ }
2458
+ function CalloutFreeTextPreview({
2459
+ calloutLine,
2460
+ textBox,
2461
+ bounds,
2462
+ scale,
2463
+ strokeColor,
2464
+ strokeWidth,
2465
+ color,
2466
+ backgroundColor,
2467
+ opacity,
2468
+ lineEnding
2469
+ }) {
2470
+ if (!calloutLine || calloutLine.length < 2) return /* @__PURE__ */ jsx(Fragment$1, {});
2471
+ const sw = strokeWidth ?? 1;
2472
+ const sc = strokeColor ?? "#000000";
2473
+ const op = opacity ?? 1;
2474
+ const w = bounds.size.width;
2475
+ const h = bounds.size.height;
2476
+ const ox = bounds.origin.x;
2477
+ const oy = bounds.origin.y;
2478
+ const lineCoords = calloutLine.map((p) => ({ x: p.x - ox, y: p.y - oy }));
2479
+ const angle = Math.atan2(lineCoords[1].y - lineCoords[0].y, lineCoords[1].x - lineCoords[0].x);
2480
+ const ending = patching.createEnding(
2481
+ lineEnding,
2482
+ sw,
2483
+ angle + Math.PI,
2484
+ lineCoords[0].x,
2485
+ lineCoords[0].y
2486
+ );
2487
+ const halfSw = sw / 2;
2488
+ return /* @__PURE__ */ jsxs(
2489
+ "svg",
2490
+ {
2491
+ style: {
2492
+ position: "absolute",
2493
+ width: w * scale,
2494
+ height: h * scale,
2495
+ pointerEvents: "none",
2496
+ overflow: "visible"
2497
+ },
2498
+ width: w * scale,
2499
+ height: h * scale,
2500
+ viewBox: `0 0 ${w} ${h}`,
2501
+ children: [
2502
+ /* @__PURE__ */ jsx(
2503
+ "polyline",
2504
+ {
2505
+ points: lineCoords.map((p) => `${p.x},${p.y}`).join(" "),
2506
+ fill: "none",
2507
+ stroke: sc,
2508
+ strokeWidth: sw,
2509
+ opacity: op
2510
+ }
2511
+ ),
2512
+ ending && /* @__PURE__ */ jsx(
2513
+ "path",
2514
+ {
2515
+ d: ending.d,
2516
+ transform: ending.transform,
2517
+ stroke: sc,
2518
+ fill: ending.filled ? color ?? "transparent" : "none",
2519
+ strokeWidth: sw,
2520
+ opacity: op
2521
+ }
2522
+ ),
2523
+ textBox && /* @__PURE__ */ jsx(
2524
+ "rect",
2525
+ {
2526
+ x: textBox.origin.x - ox + halfSw,
2527
+ y: textBox.origin.y - oy + halfSw,
2528
+ width: textBox.size.width - sw,
2529
+ height: textBox.size.height - sw,
2530
+ fill: color ?? backgroundColor ?? "transparent",
2531
+ stroke: sc,
2532
+ strokeWidth: sw,
2533
+ opacity: op
2534
+ }
2535
+ )
2536
+ ]
2537
+ }
2538
+ );
2539
+ }
2207
2540
  function RenderAnnotation({
2208
2541
  documentId,
2209
2542
  pageIndex,
@@ -2896,11 +3229,59 @@ const builtInRenderers = [
2896
3229
  ),
2897
3230
  interactionDefaults: { isDraggable: false, isResizable: false, isRotatable: false }
2898
3231
  }),
3232
+ // --- Callout FreeText (must appear before regular FreeText to match first) ---
3233
+ createRenderer({
3234
+ id: "freeTextCallout",
3235
+ matches: (a) => a.type === PdfAnnotationSubtype.FREETEXT && a.intent === "FreeTextCallout",
3236
+ matchesPreview: (p) => p.type === PdfAnnotationSubtype.FREETEXT && !!p.data.calloutLine,
3237
+ render: ({
3238
+ annotation,
3239
+ currentObject,
3240
+ isSelected,
3241
+ isEditing,
3242
+ scale,
3243
+ pageIndex,
3244
+ documentId,
3245
+ onClick,
3246
+ appearanceActive
3247
+ }) => /* @__PURE__ */ jsx(
3248
+ CalloutFreeText,
3249
+ {
3250
+ documentId,
3251
+ isSelected,
3252
+ isEditing,
3253
+ annotation: { ...annotation, object: currentObject },
3254
+ pageIndex,
3255
+ scale,
3256
+ onClick,
3257
+ appearanceActive
3258
+ }
3259
+ ),
3260
+ renderPreview: ({ data, bounds, scale }) => /* @__PURE__ */ jsx(
3261
+ CalloutFreeTextPreview,
3262
+ {
3263
+ calloutLine: data.calloutLine,
3264
+ textBox: data.textBox,
3265
+ bounds,
3266
+ scale,
3267
+ strokeColor: data.strokeColor,
3268
+ strokeWidth: data.strokeWidth,
3269
+ color: data.color,
3270
+ backgroundColor: data.backgroundColor,
3271
+ opacity: data.opacity,
3272
+ lineEnding: data.lineEnding
3273
+ }
3274
+ ),
3275
+ vertexConfig: patching.calloutVertexConfig,
3276
+ interactionDefaults: { isDraggable: true, isResizable: false, isRotatable: false },
3277
+ isDraggable: (toolDraggable, { isEditing }) => toolDraggable && !isEditing,
3278
+ onDoubleClick: (id, setEditingId) => setEditingId(id)
3279
+ }),
2899
3280
  // --- FreeText ---
2900
3281
  createRenderer({
2901
3282
  id: "freeText",
2902
- matches: (a) => a.type === PdfAnnotationSubtype.FREETEXT,
2903
- matchesPreview: (p) => p.type === PdfAnnotationSubtype.FREETEXT,
3283
+ matches: (a) => a.type === PdfAnnotationSubtype.FREETEXT && a.intent !== "FreeTextCallout",
3284
+ matchesPreview: (p) => p.type === PdfAnnotationSubtype.FREETEXT && !p.data.calloutLine,
2904
3285
  render: ({
2905
3286
  annotation,
2906
3287
  currentObject,