@embedpdf/plugin-annotation 2.5.0 → 2.6.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.
- package/dist/index.cjs +1 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +1061 -430
- package/dist/index.js.map +1 -1
- package/dist/lib/annotation-plugin.d.ts +24 -6
- package/dist/lib/geometry/index.d.ts +1 -0
- package/dist/lib/geometry/rotation.d.ts +32 -0
- package/dist/lib/handlers/types.d.ts +3 -1
- package/dist/lib/index.d.ts +1 -0
- package/dist/lib/patching/base-patch.d.ts +87 -0
- package/dist/lib/patching/index.d.ts +1 -0
- package/dist/lib/patching/insert-upright.d.ts +20 -0
- package/dist/lib/patching/patch-registry.d.ts +14 -1
- package/dist/lib/patching/patch-utils.d.ts +54 -1
- package/dist/lib/patching/patches/circle.patch.d.ts +3 -0
- package/dist/lib/patching/patches/freetext.patch.d.ts +3 -0
- package/dist/lib/patching/patches/index.d.ts +4 -0
- package/dist/lib/patching/patches/square.patch.d.ts +3 -0
- package/dist/lib/patching/patches/stamp.patch.d.ts +3 -0
- package/dist/lib/tools/default-tools.d.ts +32 -0
- package/dist/lib/tools/types.d.ts +20 -1
- package/dist/lib/types.d.ts +67 -3
- package/dist/preact/adapter.d.ts +3 -0
- package/dist/preact/index.cjs +1 -1
- package/dist/preact/index.cjs.map +1 -1
- package/dist/preact/index.js +793 -126
- package/dist/preact/index.js.map +1 -1
- package/dist/react/adapter.d.ts +2 -1
- package/dist/react/index.cjs +1 -1
- package/dist/react/index.cjs.map +1 -1
- package/dist/react/index.js +793 -126
- package/dist/react/index.js.map +1 -1
- package/dist/shared/components/annotation-container.d.ts +10 -2
- package/dist/shared/components/annotation-layer.d.ts +9 -3
- package/dist/shared/components/annotations.d.ts +4 -1
- package/dist/shared/components/group-selection-box.d.ts +12 -4
- package/dist/shared/components/render-annotation.d.ts +2 -1
- package/dist/shared/components/types.d.ts +51 -1
- package/dist/shared-preact/components/annotation-container.d.ts +10 -2
- package/dist/shared-preact/components/annotation-layer.d.ts +9 -3
- package/dist/shared-preact/components/annotations.d.ts +4 -1
- package/dist/shared-preact/components/group-selection-box.d.ts +12 -4
- package/dist/shared-preact/components/render-annotation.d.ts +2 -1
- package/dist/shared-preact/components/types.d.ts +51 -1
- package/dist/shared-react/components/annotation-container.d.ts +10 -2
- package/dist/shared-react/components/annotation-layer.d.ts +9 -3
- package/dist/shared-react/components/annotations.d.ts +4 -1
- package/dist/shared-react/components/group-selection-box.d.ts +12 -4
- package/dist/shared-react/components/render-annotation.d.ts +2 -1
- package/dist/shared-react/components/types.d.ts +51 -1
- package/dist/svelte/components/AnnotationLayer.svelte.d.ts +8 -2
- package/dist/svelte/components/Annotations.svelte.d.ts +7 -1
- package/dist/svelte/components/GroupSelectionBox.svelte.d.ts +11 -3
- package/dist/svelte/components/RenderAnnotation.svelte.d.ts +1 -0
- package/dist/svelte/components/types.d.ts +14 -1
- package/dist/svelte/index.cjs +1 -1
- package/dist/svelte/index.cjs.map +1 -1
- package/dist/svelte/index.js +1166 -330
- package/dist/svelte/index.js.map +1 -1
- package/dist/svelte/types.d.ts +53 -0
- package/dist/vue/components/annotation-container.vue.d.ts +35 -9
- package/dist/vue/components/annotation-layer.vue.d.ts +29 -5
- package/dist/vue/components/annotations.vue.d.ts +278 -134
- package/dist/vue/components/group-selection-box.vue.d.ts +35 -10
- package/dist/vue/components/render-annotation.vue.d.ts +2 -0
- package/dist/vue/index.cjs +1 -1
- package/dist/vue/index.cjs.map +1 -1
- package/dist/vue/index.js +945 -161
- package/dist/vue/index.js.map +1 -1
- package/dist/vue/types.d.ts +52 -0
- package/package.json +11 -10
package/dist/index.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { clamp, BasePlugin, createBehaviorEmitter } from "@embedpdf/core";
|
|
2
|
-
import { PdfAnnotationSubtype, PdfAnnotationReplyType, PdfBlendMode, PdfAnnotationBorderStyle, PdfAnnotationLineEnding, PdfVerticalAlignment, PdfTextAlignment, PdfStandardFont, expandRect, rectFromPoints, uuidV4, rotateAndTranslatePoint, PdfAnnotationIcon, PdfPermissionFlag, ignore, PdfTaskHelper, PdfErrorCode, Task, TaskStage } from "@embedpdf/models";
|
|
2
|
+
import { PdfAnnotationSubtype, PdfAnnotationReplyType, PdfBlendMode, PdfAnnotationBorderStyle, PdfAnnotationLineEnding, PdfVerticalAlignment, PdfTextAlignment, PdfStandardFont, expandRect, rectFromPoints, uuidV4, getRectCenter, inferRotationCenterFromRects, calculateRotatedRectAABBAroundPoint, rotateAndTranslatePoint, calculateRotatedRectAABB, rotatePointAround, rotateVertices, PdfAnnotationIcon, PdfPermissionFlag, ignore, PdfTaskHelper, PdfErrorCode, Task, TaskStage } from "@embedpdf/models";
|
|
3
|
+
import { calculateRotatedRectAABB as calculateRotatedRectAABB2, calculateRotatedRectAABBAroundPoint as calculateRotatedRectAABBAroundPoint2, getRectCenter as getRectCenter2, inferRotationCenterFromRects as inferRotationCenterFromRects2, rotatePointAround as rotatePointAround2, rotateVertices as rotateVertices2 } from "@embedpdf/models";
|
|
3
4
|
const ANNOTATION_PLUGIN_ID = "annotation";
|
|
4
5
|
const manifest = {
|
|
5
6
|
id: ANNOTATION_PLUGIN_ID,
|
|
@@ -431,7 +432,11 @@ const defaultTools = [
|
|
|
431
432
|
cursor: "crosshair",
|
|
432
433
|
isDraggable: true,
|
|
433
434
|
isResizable: true,
|
|
434
|
-
lockAspectRatio: false
|
|
435
|
+
lockAspectRatio: false,
|
|
436
|
+
lockGroupAspectRatio: (a) => {
|
|
437
|
+
const r = ((a.rotation ?? 0) % 90 + 90) % 90;
|
|
438
|
+
return r >= 6 && r <= 84;
|
|
439
|
+
}
|
|
435
440
|
},
|
|
436
441
|
defaults: {
|
|
437
442
|
type: PdfAnnotationSubtype.INK,
|
|
@@ -454,7 +459,11 @@ const defaultTools = [
|
|
|
454
459
|
cursor: "crosshair",
|
|
455
460
|
isDraggable: true,
|
|
456
461
|
isResizable: true,
|
|
457
|
-
lockAspectRatio: false
|
|
462
|
+
lockAspectRatio: false,
|
|
463
|
+
lockGroupAspectRatio: (a) => {
|
|
464
|
+
const r = ((a.rotation ?? 0) % 90 + 90) % 90;
|
|
465
|
+
return r >= 6 && r <= 84;
|
|
466
|
+
}
|
|
458
467
|
},
|
|
459
468
|
defaults: {
|
|
460
469
|
type: PdfAnnotationSubtype.CIRCLE,
|
|
@@ -478,7 +487,11 @@ const defaultTools = [
|
|
|
478
487
|
cursor: "crosshair",
|
|
479
488
|
isDraggable: true,
|
|
480
489
|
isResizable: true,
|
|
481
|
-
lockAspectRatio: false
|
|
490
|
+
lockAspectRatio: false,
|
|
491
|
+
lockGroupAspectRatio: (a) => {
|
|
492
|
+
const r = ((a.rotation ?? 0) % 90 + 90) % 90;
|
|
493
|
+
return r >= 6 && r <= 84;
|
|
494
|
+
}
|
|
482
495
|
},
|
|
483
496
|
defaults: {
|
|
484
497
|
type: PdfAnnotationSubtype.SQUARE,
|
|
@@ -504,8 +517,12 @@ const defaultTools = [
|
|
|
504
517
|
isResizable: false,
|
|
505
518
|
// Uses vertex editing when selected individually
|
|
506
519
|
lockAspectRatio: false,
|
|
507
|
-
isGroupResizable: true
|
|
520
|
+
isGroupResizable: true,
|
|
508
521
|
// Scales proportionally in a group
|
|
522
|
+
lockGroupAspectRatio: (a) => {
|
|
523
|
+
const r = ((a.rotation ?? 0) % 90 + 90) % 90;
|
|
524
|
+
return r >= 6 && r <= 84;
|
|
525
|
+
}
|
|
509
526
|
},
|
|
510
527
|
defaults: {
|
|
511
528
|
type: PdfAnnotationSubtype.LINE,
|
|
@@ -531,8 +548,12 @@ const defaultTools = [
|
|
|
531
548
|
isResizable: false,
|
|
532
549
|
// Uses vertex editing when selected individually
|
|
533
550
|
lockAspectRatio: false,
|
|
534
|
-
isGroupResizable: true
|
|
551
|
+
isGroupResizable: true,
|
|
535
552
|
// Scales proportionally in a group
|
|
553
|
+
lockGroupAspectRatio: (a) => {
|
|
554
|
+
const r = ((a.rotation ?? 0) % 90 + 90) % 90;
|
|
555
|
+
return r >= 6 && r <= 84;
|
|
556
|
+
}
|
|
536
557
|
},
|
|
537
558
|
defaults: {
|
|
538
559
|
type: PdfAnnotationSubtype.LINE,
|
|
@@ -563,8 +584,12 @@ const defaultTools = [
|
|
|
563
584
|
isResizable: false,
|
|
564
585
|
// Uses vertex editing when selected individually
|
|
565
586
|
lockAspectRatio: false,
|
|
566
|
-
isGroupResizable: true
|
|
587
|
+
isGroupResizable: true,
|
|
567
588
|
// Scales proportionally in a group
|
|
589
|
+
lockGroupAspectRatio: (a) => {
|
|
590
|
+
const r = ((a.rotation ?? 0) % 90 + 90) % 90;
|
|
591
|
+
return r >= 6 && r <= 84;
|
|
592
|
+
}
|
|
568
593
|
},
|
|
569
594
|
defaults: {
|
|
570
595
|
type: PdfAnnotationSubtype.POLYLINE,
|
|
@@ -585,8 +610,12 @@ const defaultTools = [
|
|
|
585
610
|
isResizable: false,
|
|
586
611
|
// Uses vertex editing when selected individually
|
|
587
612
|
lockAspectRatio: false,
|
|
588
|
-
isGroupResizable: true
|
|
613
|
+
isGroupResizable: true,
|
|
589
614
|
// Scales proportionally in a group
|
|
615
|
+
lockGroupAspectRatio: (a) => {
|
|
616
|
+
const r = ((a.rotation ?? 0) % 90 + 90) % 90;
|
|
617
|
+
return r >= 6 && r <= 84;
|
|
618
|
+
}
|
|
590
619
|
},
|
|
591
620
|
defaults: {
|
|
592
621
|
type: PdfAnnotationSubtype.POLYGON,
|
|
@@ -606,7 +635,11 @@ const defaultTools = [
|
|
|
606
635
|
cursor: "crosshair",
|
|
607
636
|
isDraggable: true,
|
|
608
637
|
isResizable: true,
|
|
609
|
-
lockAspectRatio: false
|
|
638
|
+
lockAspectRatio: false,
|
|
639
|
+
lockGroupAspectRatio: (a) => {
|
|
640
|
+
const r = ((a.rotation ?? 0) % 90 + 90) % 90;
|
|
641
|
+
return r >= 6 && r <= 84;
|
|
642
|
+
}
|
|
610
643
|
},
|
|
611
644
|
defaults: {
|
|
612
645
|
type: PdfAnnotationSubtype.FREETEXT,
|
|
@@ -626,6 +659,9 @@ const defaultTools = [
|
|
|
626
659
|
enabled: true,
|
|
627
660
|
defaultSize: { width: 100, height: 20 },
|
|
628
661
|
defaultContent: "Insert text"
|
|
662
|
+
},
|
|
663
|
+
behavior: {
|
|
664
|
+
insertUpright: true
|
|
629
665
|
}
|
|
630
666
|
},
|
|
631
667
|
{
|
|
@@ -637,11 +673,15 @@ const defaultTools = [
|
|
|
637
673
|
cursor: "copy",
|
|
638
674
|
isDraggable: true,
|
|
639
675
|
isResizable: true,
|
|
640
|
-
lockAspectRatio: true
|
|
676
|
+
lockAspectRatio: true,
|
|
677
|
+
lockGroupAspectRatio: true
|
|
641
678
|
},
|
|
642
679
|
defaults: {
|
|
643
680
|
type: PdfAnnotationSubtype.STAMP
|
|
644
681
|
// No imageSrc by default, which tells the UI to open a file picker
|
|
682
|
+
},
|
|
683
|
+
behavior: {
|
|
684
|
+
insertUpright: true
|
|
645
685
|
}
|
|
646
686
|
}
|
|
647
687
|
];
|
|
@@ -683,14 +723,44 @@ const patchAnno = (docState, uid, patch) => {
|
|
|
683
723
|
};
|
|
684
724
|
};
|
|
685
725
|
const initialState = (cfg) => {
|
|
686
|
-
const
|
|
687
|
-
defaultTools.forEach((t) =>
|
|
688
|
-
|
|
726
|
+
const defaultMap = /* @__PURE__ */ new Map();
|
|
727
|
+
defaultTools.forEach((t) => defaultMap.set(t.id, t));
|
|
728
|
+
const toolMap = new Map(defaultMap);
|
|
729
|
+
(cfg.tools || []).forEach((userTool) => {
|
|
730
|
+
const base = defaultMap.get(userTool.id);
|
|
731
|
+
if (base) {
|
|
732
|
+
toolMap.set(userTool.id, {
|
|
733
|
+
...base,
|
|
734
|
+
...userTool,
|
|
735
|
+
defaults: { ...base.defaults, ...userTool.defaults },
|
|
736
|
+
interaction: { ...base.interaction, ...userTool.interaction },
|
|
737
|
+
behavior: { ...base.behavior, ...userTool.behavior },
|
|
738
|
+
...base.clickBehavior || userTool.clickBehavior ? {
|
|
739
|
+
clickBehavior: {
|
|
740
|
+
...base.clickBehavior,
|
|
741
|
+
...userTool.clickBehavior
|
|
742
|
+
}
|
|
743
|
+
} : {}
|
|
744
|
+
});
|
|
745
|
+
} else {
|
|
746
|
+
toolMap.set(userTool.id, userTool);
|
|
747
|
+
}
|
|
748
|
+
});
|
|
749
|
+
const tools = Array.from(toolMap.values()).map((t) => {
|
|
750
|
+
var _a, _b;
|
|
751
|
+
return {
|
|
752
|
+
...t,
|
|
753
|
+
behavior: {
|
|
754
|
+
...t.behavior,
|
|
755
|
+
deactivateToolAfterCreate: ((_a = t.behavior) == null ? void 0 : _a.deactivateToolAfterCreate) ?? cfg.deactivateToolAfterCreate ?? false,
|
|
756
|
+
selectAfterCreate: ((_b = t.behavior) == null ? void 0 : _b.selectAfterCreate) ?? cfg.selectAfterCreate ?? true
|
|
757
|
+
}
|
|
758
|
+
};
|
|
759
|
+
});
|
|
689
760
|
return {
|
|
690
761
|
documents: {},
|
|
691
762
|
activeDocumentId: null,
|
|
692
|
-
|
|
693
|
-
tools: Array.from(toolMap.values()),
|
|
763
|
+
tools,
|
|
694
764
|
colorPresets: cfg.colorPresets ?? DEFAULT_COLORS
|
|
695
765
|
};
|
|
696
766
|
};
|
|
@@ -1115,149 +1185,6 @@ function useClickDetector({
|
|
|
1115
1185
|
}
|
|
1116
1186
|
};
|
|
1117
1187
|
}
|
|
1118
|
-
const freeTextHandlerFactory = {
|
|
1119
|
-
annotationType: PdfAnnotationSubtype.FREETEXT,
|
|
1120
|
-
create(context) {
|
|
1121
|
-
const { onCommit, onPreview, getTool, pageSize, pageIndex } = context;
|
|
1122
|
-
const [getStart, setStart] = useState(null);
|
|
1123
|
-
const clampToPage = (pos) => ({
|
|
1124
|
-
x: clamp(pos.x, 0, pageSize.width),
|
|
1125
|
-
y: clamp(pos.y, 0, pageSize.height)
|
|
1126
|
-
});
|
|
1127
|
-
const getDefaults = () => {
|
|
1128
|
-
const tool = getTool();
|
|
1129
|
-
if (!tool) return null;
|
|
1130
|
-
return {
|
|
1131
|
-
...tool.defaults,
|
|
1132
|
-
fontColor: tool.defaults.fontColor ?? "#000000",
|
|
1133
|
-
opacity: tool.defaults.opacity ?? 1,
|
|
1134
|
-
fontSize: tool.defaults.fontSize ?? 12,
|
|
1135
|
-
fontFamily: tool.defaults.fontFamily ?? PdfStandardFont.Helvetica,
|
|
1136
|
-
color: tool.defaults.color ?? tool.defaults.backgroundColor ?? "transparent",
|
|
1137
|
-
textAlign: tool.defaults.textAlign ?? PdfTextAlignment.Left,
|
|
1138
|
-
verticalAlign: tool.defaults.verticalAlign ?? PdfVerticalAlignment.Top,
|
|
1139
|
-
contents: tool.defaults.contents ?? "Insert text here",
|
|
1140
|
-
flags: tool.defaults.flags ?? ["print"]
|
|
1141
|
-
};
|
|
1142
|
-
};
|
|
1143
|
-
const clickDetector = useClickDetector({
|
|
1144
|
-
threshold: 5,
|
|
1145
|
-
getTool,
|
|
1146
|
-
onClickDetected: (pos, tool) => {
|
|
1147
|
-
const defaults = getDefaults();
|
|
1148
|
-
if (!defaults) return;
|
|
1149
|
-
const clickConfig = tool.clickBehavior;
|
|
1150
|
-
if (!(clickConfig == null ? void 0 : clickConfig.enabled)) return;
|
|
1151
|
-
const { width, height } = clickConfig.defaultSize;
|
|
1152
|
-
const halfWidth = width / 2;
|
|
1153
|
-
const halfHeight = height / 2;
|
|
1154
|
-
const x = clamp(pos.x - halfWidth, 0, pageSize.width - width);
|
|
1155
|
-
const y = clamp(pos.y - halfHeight, 0, pageSize.height - height);
|
|
1156
|
-
const rect = {
|
|
1157
|
-
origin: { x, y },
|
|
1158
|
-
size: { width, height }
|
|
1159
|
-
};
|
|
1160
|
-
const contents = clickConfig.defaultContent ?? defaults.contents;
|
|
1161
|
-
const anno = {
|
|
1162
|
-
...defaults,
|
|
1163
|
-
contents,
|
|
1164
|
-
type: PdfAnnotationSubtype.FREETEXT,
|
|
1165
|
-
rect,
|
|
1166
|
-
pageIndex,
|
|
1167
|
-
id: uuidV4(),
|
|
1168
|
-
created: /* @__PURE__ */ new Date()
|
|
1169
|
-
};
|
|
1170
|
-
onCommit(anno);
|
|
1171
|
-
}
|
|
1172
|
-
});
|
|
1173
|
-
const getPreview = (current) => {
|
|
1174
|
-
const start = getStart();
|
|
1175
|
-
if (!start) return null;
|
|
1176
|
-
const defaults = getDefaults();
|
|
1177
|
-
if (!defaults) return null;
|
|
1178
|
-
const minX = Math.min(start.x, current.x);
|
|
1179
|
-
const minY = Math.min(start.y, current.y);
|
|
1180
|
-
const width = Math.abs(start.x - current.x);
|
|
1181
|
-
const height = Math.abs(start.y - current.y);
|
|
1182
|
-
const rect = {
|
|
1183
|
-
origin: { x: minX, y: minY },
|
|
1184
|
-
size: { width, height }
|
|
1185
|
-
};
|
|
1186
|
-
return {
|
|
1187
|
-
type: PdfAnnotationSubtype.FREETEXT,
|
|
1188
|
-
bounds: rect,
|
|
1189
|
-
data: {
|
|
1190
|
-
...defaults,
|
|
1191
|
-
rect
|
|
1192
|
-
}
|
|
1193
|
-
};
|
|
1194
|
-
};
|
|
1195
|
-
return {
|
|
1196
|
-
onPointerDown: (pos, evt) => {
|
|
1197
|
-
var _a;
|
|
1198
|
-
const clampedPos = clampToPage(pos);
|
|
1199
|
-
setStart(clampedPos);
|
|
1200
|
-
clickDetector.onStart(clampedPos);
|
|
1201
|
-
onPreview(getPreview(clampedPos));
|
|
1202
|
-
(_a = evt.setPointerCapture) == null ? void 0 : _a.call(evt);
|
|
1203
|
-
},
|
|
1204
|
-
onPointerMove: (pos) => {
|
|
1205
|
-
const clampedPos = clampToPage(pos);
|
|
1206
|
-
clickDetector.onMove(clampedPos);
|
|
1207
|
-
if (getStart() && clickDetector.hasMoved()) {
|
|
1208
|
-
onPreview(getPreview(clampedPos));
|
|
1209
|
-
}
|
|
1210
|
-
},
|
|
1211
|
-
onPointerUp: (pos, evt) => {
|
|
1212
|
-
var _a;
|
|
1213
|
-
const start = getStart();
|
|
1214
|
-
if (!start) return;
|
|
1215
|
-
const defaults = getDefaults();
|
|
1216
|
-
if (!defaults) return;
|
|
1217
|
-
const clampedPos = clampToPage(pos);
|
|
1218
|
-
if (!clickDetector.hasMoved()) {
|
|
1219
|
-
clickDetector.onEnd(clampedPos);
|
|
1220
|
-
} else {
|
|
1221
|
-
const minX = Math.min(start.x, clampedPos.x);
|
|
1222
|
-
const minY = Math.min(start.y, clampedPos.y);
|
|
1223
|
-
const width = Math.abs(start.x - clampedPos.x);
|
|
1224
|
-
const height = Math.abs(start.y - clampedPos.y);
|
|
1225
|
-
const rect = {
|
|
1226
|
-
origin: { x: minX, y: minY },
|
|
1227
|
-
size: { width, height }
|
|
1228
|
-
};
|
|
1229
|
-
const anno = {
|
|
1230
|
-
...defaults,
|
|
1231
|
-
type: PdfAnnotationSubtype.FREETEXT,
|
|
1232
|
-
rect,
|
|
1233
|
-
pageIndex: context.pageIndex,
|
|
1234
|
-
id: uuidV4(),
|
|
1235
|
-
created: /* @__PURE__ */ new Date()
|
|
1236
|
-
};
|
|
1237
|
-
onCommit(anno);
|
|
1238
|
-
}
|
|
1239
|
-
setStart(null);
|
|
1240
|
-
onPreview(null);
|
|
1241
|
-
clickDetector.reset();
|
|
1242
|
-
(_a = evt.releasePointerCapture) == null ? void 0 : _a.call(evt);
|
|
1243
|
-
},
|
|
1244
|
-
onPointerLeave: (_, evt) => {
|
|
1245
|
-
var _a;
|
|
1246
|
-
setStart(null);
|
|
1247
|
-
onPreview(null);
|
|
1248
|
-
clickDetector.reset();
|
|
1249
|
-
(_a = evt.releasePointerCapture) == null ? void 0 : _a.call(evt);
|
|
1250
|
-
},
|
|
1251
|
-
onPointerCancel: (_, evt) => {
|
|
1252
|
-
var _a;
|
|
1253
|
-
setStart(null);
|
|
1254
|
-
onPreview(null);
|
|
1255
|
-
clickDetector.reset();
|
|
1256
|
-
(_a = evt.releasePointerCapture) == null ? void 0 : _a.call(evt);
|
|
1257
|
-
}
|
|
1258
|
-
};
|
|
1259
|
-
}
|
|
1260
|
-
};
|
|
1261
1188
|
function createArrowHandler(isClosed) {
|
|
1262
1189
|
const calculateGeometry = (sw) => {
|
|
1263
1190
|
const len = sw * 9;
|
|
@@ -1373,6 +1300,13 @@ const LINE_ENDING_HANDLERS = {
|
|
|
1373
1300
|
[PdfAnnotationLineEnding.Slash]: createLineHandler(18, (angle) => angle + Math.PI / 1.5)
|
|
1374
1301
|
};
|
|
1375
1302
|
const EXTRA_PADDING = 1.2;
|
|
1303
|
+
function calculateAABBFromVertices(vertices, padding = 0) {
|
|
1304
|
+
if (vertices.length === 0) {
|
|
1305
|
+
return { origin: { x: 0, y: 0 }, size: { width: 0, height: 0 } };
|
|
1306
|
+
}
|
|
1307
|
+
const baseRect = rectFromPoints(vertices);
|
|
1308
|
+
return padding > 0 ? expandRect(baseRect, padding) : baseRect;
|
|
1309
|
+
}
|
|
1376
1310
|
function lineRectWithEndings(vertices, strokeWidth, endings) {
|
|
1377
1311
|
if (!vertices || vertices.length === 0) {
|
|
1378
1312
|
return { origin: { x: 0, y: 0 }, size: { width: 0, height: 0 } };
|
|
@@ -1407,6 +1341,54 @@ function lineRectWithEndings(vertices, strokeWidth, endings) {
|
|
|
1407
1341
|
const pad = strokeWidth / 2 + EXTRA_PADDING * strokeWidth;
|
|
1408
1342
|
return expandRect(baseRect, pad);
|
|
1409
1343
|
}
|
|
1344
|
+
function resolveVertexEditRects(original, tightRect) {
|
|
1345
|
+
if (!original.unrotatedRect) return { rect: tightRect };
|
|
1346
|
+
const center = getRectCenter(tightRect);
|
|
1347
|
+
return {
|
|
1348
|
+
rect: calculateRotatedRectAABBAroundPoint(tightRect, original.rotation ?? 0, center),
|
|
1349
|
+
unrotatedRect: tightRect
|
|
1350
|
+
};
|
|
1351
|
+
}
|
|
1352
|
+
function resolveAnnotationRotationCenter(original) {
|
|
1353
|
+
if (!original.unrotatedRect) return getRectCenter(original.rect);
|
|
1354
|
+
return inferRotationCenterFromRects(
|
|
1355
|
+
original.unrotatedRect,
|
|
1356
|
+
original.rect,
|
|
1357
|
+
original.rotation ?? 0
|
|
1358
|
+
);
|
|
1359
|
+
}
|
|
1360
|
+
function resolveRotateRects(original, nextUnrotatedRect, angleDegrees) {
|
|
1361
|
+
const baseCenter = resolveAnnotationRotationCenter(original);
|
|
1362
|
+
const baseRect = original.unrotatedRect ?? original.rect;
|
|
1363
|
+
const translation = {
|
|
1364
|
+
x: nextUnrotatedRect.origin.x - baseRect.origin.x,
|
|
1365
|
+
y: nextUnrotatedRect.origin.y - baseRect.origin.y
|
|
1366
|
+
};
|
|
1367
|
+
const nextCenter = {
|
|
1368
|
+
x: baseCenter.x + translation.x,
|
|
1369
|
+
y: baseCenter.y + translation.y
|
|
1370
|
+
};
|
|
1371
|
+
return {
|
|
1372
|
+
rect: calculateRotatedRectAABBAroundPoint(nextUnrotatedRect, angleDegrees, nextCenter),
|
|
1373
|
+
unrotatedRect: nextUnrotatedRect
|
|
1374
|
+
};
|
|
1375
|
+
}
|
|
1376
|
+
function compensateRotatedVertexEdit(original, vertices, tightRect) {
|
|
1377
|
+
if (!original.unrotatedRect) return vertices;
|
|
1378
|
+
const angle = original.rotation ?? 0;
|
|
1379
|
+
if (Math.abs(angle % 360) < 1e-8) return vertices;
|
|
1380
|
+
const baseCenter = resolveAnnotationRotationCenter(original);
|
|
1381
|
+
const nextCenter = getRectCenter(tightRect);
|
|
1382
|
+
const rad = angle * Math.PI / 180;
|
|
1383
|
+
const cos = Math.cos(rad);
|
|
1384
|
+
const sin = Math.sin(rad);
|
|
1385
|
+
const dx = baseCenter.x - nextCenter.x;
|
|
1386
|
+
const dy = baseCenter.y - nextCenter.y;
|
|
1387
|
+
const qx = (1 - cos) * dx + sin * dy;
|
|
1388
|
+
const qy = -sin * dx + (1 - cos) * dy;
|
|
1389
|
+
if (Math.abs(qx) < 1e-8 && Math.abs(qy) < 1e-8) return vertices;
|
|
1390
|
+
return vertices.map((v) => ({ x: v.x + qx, y: v.y + qy }));
|
|
1391
|
+
}
|
|
1410
1392
|
function createEnding(ending, strokeWidth, rad, px, py) {
|
|
1411
1393
|
if (!ending) return null;
|
|
1412
1394
|
const handler = LINE_ENDING_HANDLERS[ending];
|
|
@@ -1439,14 +1421,298 @@ class PatchRegistry {
|
|
|
1439
1421
|
}
|
|
1440
1422
|
}
|
|
1441
1423
|
const patchRegistry = new PatchRegistry();
|
|
1424
|
+
function baseRotateChanges(orig, ctx) {
|
|
1425
|
+
var _a;
|
|
1426
|
+
if (((_a = ctx.metadata) == null ? void 0 : _a.rotationAngle) === void 0) return null;
|
|
1427
|
+
const angleDegrees = ctx.metadata.rotationAngle;
|
|
1428
|
+
const baseUnrotatedRect = ctx.changes.unrotatedRect ?? orig.unrotatedRect ?? orig.rect;
|
|
1429
|
+
const normalizedUnrotatedRect = {
|
|
1430
|
+
origin: { ...baseUnrotatedRect.origin },
|
|
1431
|
+
size: { ...baseUnrotatedRect.size }
|
|
1432
|
+
};
|
|
1433
|
+
return {
|
|
1434
|
+
...resolveRotateRects(orig, normalizedUnrotatedRect, angleDegrees),
|
|
1435
|
+
rotation: angleDegrees
|
|
1436
|
+
};
|
|
1437
|
+
}
|
|
1438
|
+
function basePropertyRotationChanges(orig, newRotation) {
|
|
1439
|
+
const unrotatedRect = orig.unrotatedRect ?? orig.rect;
|
|
1440
|
+
return {
|
|
1441
|
+
rotation: newRotation,
|
|
1442
|
+
...resolveRotateRects(orig, unrotatedRect, newRotation)
|
|
1443
|
+
};
|
|
1444
|
+
}
|
|
1445
|
+
function baseMoveChanges(orig, newRect) {
|
|
1446
|
+
const dx = newRect.origin.x - orig.rect.origin.x;
|
|
1447
|
+
const dy = newRect.origin.y - orig.rect.origin.y;
|
|
1448
|
+
const rects = { rect: newRect };
|
|
1449
|
+
if (orig.unrotatedRect) {
|
|
1450
|
+
rects.unrotatedRect = {
|
|
1451
|
+
origin: { x: orig.unrotatedRect.origin.x + dx, y: orig.unrotatedRect.origin.y + dy },
|
|
1452
|
+
size: { ...orig.unrotatedRect.size }
|
|
1453
|
+
};
|
|
1454
|
+
}
|
|
1455
|
+
return { dx, dy, rects };
|
|
1456
|
+
}
|
|
1457
|
+
function baseResizeScaling(orig, newRect, metadata) {
|
|
1458
|
+
const oldRect = orig.unrotatedRect ?? orig.rect;
|
|
1459
|
+
let scaleX = newRect.size.width / oldRect.size.width;
|
|
1460
|
+
let scaleY = newRect.size.height / oldRect.size.height;
|
|
1461
|
+
const minSize = 10;
|
|
1462
|
+
if (newRect.size.width < minSize || newRect.size.height < minSize) {
|
|
1463
|
+
scaleX = Math.max(scaleX, minSize / oldRect.size.width);
|
|
1464
|
+
scaleY = Math.max(scaleY, minSize / oldRect.size.height);
|
|
1465
|
+
newRect = {
|
|
1466
|
+
origin: newRect.origin,
|
|
1467
|
+
size: {
|
|
1468
|
+
width: oldRect.size.width * scaleX,
|
|
1469
|
+
height: oldRect.size.height * scaleY
|
|
1470
|
+
}
|
|
1471
|
+
};
|
|
1472
|
+
}
|
|
1473
|
+
if (metadata == null ? void 0 : metadata.maintainAspectRatio) {
|
|
1474
|
+
const minScale = Math.min(scaleX, scaleY);
|
|
1475
|
+
scaleX = minScale;
|
|
1476
|
+
scaleY = minScale;
|
|
1477
|
+
newRect = {
|
|
1478
|
+
origin: newRect.origin,
|
|
1479
|
+
size: {
|
|
1480
|
+
width: oldRect.size.width * minScale,
|
|
1481
|
+
height: oldRect.size.height * minScale
|
|
1482
|
+
}
|
|
1483
|
+
};
|
|
1484
|
+
}
|
|
1485
|
+
const rects = orig.unrotatedRect ? {
|
|
1486
|
+
unrotatedRect: newRect,
|
|
1487
|
+
rect: calculateRotatedRectAABB(newRect, orig.rotation ?? 0)
|
|
1488
|
+
} : { rect: newRect };
|
|
1489
|
+
return { scaleX, scaleY, oldRect, resolvedRect: newRect, rects };
|
|
1490
|
+
}
|
|
1491
|
+
function rotateOrbitDelta(orig, rotateResult) {
|
|
1492
|
+
const baseRect = orig.unrotatedRect ?? orig.rect;
|
|
1493
|
+
const newRect = rotateResult.unrotatedRect ?? baseRect;
|
|
1494
|
+
return {
|
|
1495
|
+
dx: newRect.origin.x - baseRect.origin.x,
|
|
1496
|
+
dy: newRect.origin.y - baseRect.origin.y
|
|
1497
|
+
};
|
|
1498
|
+
}
|
|
1499
|
+
function applyInsertUpright(annotation, pageRotation, rectWasDrawn) {
|
|
1500
|
+
if (pageRotation === 0 || annotation.rotation !== void 0) return annotation;
|
|
1501
|
+
const counterDeg = (4 - pageRotation) % 4 * 90;
|
|
1502
|
+
let baseAnnotation = annotation;
|
|
1503
|
+
if (rectWasDrawn && (pageRotation === 1 || pageRotation === 3)) {
|
|
1504
|
+
const originalRect = annotation.rect;
|
|
1505
|
+
const centerX = originalRect.origin.x + originalRect.size.width / 2;
|
|
1506
|
+
const centerY = originalRect.origin.y + originalRect.size.height / 2;
|
|
1507
|
+
baseAnnotation = {
|
|
1508
|
+
...annotation,
|
|
1509
|
+
rect: {
|
|
1510
|
+
origin: {
|
|
1511
|
+
x: centerX - originalRect.size.height / 2,
|
|
1512
|
+
y: centerY - originalRect.size.width / 2
|
|
1513
|
+
},
|
|
1514
|
+
size: {
|
|
1515
|
+
width: originalRect.size.height,
|
|
1516
|
+
height: originalRect.size.width
|
|
1517
|
+
}
|
|
1518
|
+
}
|
|
1519
|
+
};
|
|
1520
|
+
}
|
|
1521
|
+
const { rotation, rect, unrotatedRect } = basePropertyRotationChanges(baseAnnotation, counterDeg);
|
|
1522
|
+
return { ...baseAnnotation, rotation, rect, unrotatedRect };
|
|
1523
|
+
}
|
|
1524
|
+
function clampAnnotationToPage(annotation, pageSize) {
|
|
1525
|
+
const clampedX = clamp(annotation.rect.origin.x, 0, pageSize.width - annotation.rect.size.width);
|
|
1526
|
+
const clampedY = clamp(
|
|
1527
|
+
annotation.rect.origin.y,
|
|
1528
|
+
0,
|
|
1529
|
+
pageSize.height - annotation.rect.size.height
|
|
1530
|
+
);
|
|
1531
|
+
const shiftX = clampedX - annotation.rect.origin.x;
|
|
1532
|
+
const shiftY = clampedY - annotation.rect.origin.y;
|
|
1533
|
+
if (shiftX === 0 && shiftY === 0) return annotation;
|
|
1534
|
+
return {
|
|
1535
|
+
...annotation,
|
|
1536
|
+
rect: { origin: { x: clampedX, y: clampedY }, size: annotation.rect.size },
|
|
1537
|
+
...annotation.unrotatedRect ? {
|
|
1538
|
+
unrotatedRect: {
|
|
1539
|
+
origin: {
|
|
1540
|
+
x: annotation.unrotatedRect.origin.x + shiftX,
|
|
1541
|
+
y: annotation.unrotatedRect.origin.y + shiftY
|
|
1542
|
+
},
|
|
1543
|
+
size: annotation.unrotatedRect.size
|
|
1544
|
+
}
|
|
1545
|
+
} : {}
|
|
1546
|
+
};
|
|
1547
|
+
}
|
|
1442
1548
|
const index = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
1443
1549
|
__proto__: null,
|
|
1444
1550
|
LINE_ENDING_HANDLERS,
|
|
1445
1551
|
PatchRegistry,
|
|
1552
|
+
applyInsertUpright,
|
|
1553
|
+
calculateAABBFromVertices,
|
|
1554
|
+
calculateRotatedRectAABB,
|
|
1555
|
+
calculateRotatedRectAABBAroundPoint,
|
|
1556
|
+
clampAnnotationToPage,
|
|
1557
|
+
compensateRotatedVertexEdit,
|
|
1446
1558
|
createEnding,
|
|
1559
|
+
getRectCenter,
|
|
1447
1560
|
lineRectWithEndings,
|
|
1448
|
-
patchRegistry
|
|
1561
|
+
patchRegistry,
|
|
1562
|
+
resolveAnnotationRotationCenter,
|
|
1563
|
+
resolveRotateRects,
|
|
1564
|
+
resolveVertexEditRects,
|
|
1565
|
+
rotatePointAroundCenter: rotatePointAround,
|
|
1566
|
+
rotateVertices
|
|
1449
1567
|
}, Symbol.toStringTag, { value: "Module" }));
|
|
1568
|
+
const freeTextHandlerFactory = {
|
|
1569
|
+
annotationType: PdfAnnotationSubtype.FREETEXT,
|
|
1570
|
+
create(context) {
|
|
1571
|
+
const { onCommit, onPreview, getTool, pageSize, pageIndex, pageRotation } = context;
|
|
1572
|
+
const [getStart, setStart] = useState(null);
|
|
1573
|
+
const clampToPage = (pos) => ({
|
|
1574
|
+
x: clamp(pos.x, 0, pageSize.width),
|
|
1575
|
+
y: clamp(pos.y, 0, pageSize.height)
|
|
1576
|
+
});
|
|
1577
|
+
const getDefaults = () => {
|
|
1578
|
+
const tool = getTool();
|
|
1579
|
+
if (!tool) return null;
|
|
1580
|
+
return {
|
|
1581
|
+
...tool.defaults,
|
|
1582
|
+
fontColor: tool.defaults.fontColor ?? "#000000",
|
|
1583
|
+
opacity: tool.defaults.opacity ?? 1,
|
|
1584
|
+
fontSize: tool.defaults.fontSize ?? 12,
|
|
1585
|
+
fontFamily: tool.defaults.fontFamily ?? PdfStandardFont.Helvetica,
|
|
1586
|
+
color: tool.defaults.color ?? tool.defaults.backgroundColor ?? "transparent",
|
|
1587
|
+
textAlign: tool.defaults.textAlign ?? PdfTextAlignment.Left,
|
|
1588
|
+
verticalAlign: tool.defaults.verticalAlign ?? PdfVerticalAlignment.Top,
|
|
1589
|
+
contents: tool.defaults.contents ?? "Insert text here",
|
|
1590
|
+
flags: tool.defaults.flags ?? ["print"]
|
|
1591
|
+
};
|
|
1592
|
+
};
|
|
1593
|
+
const clickDetector = useClickDetector({
|
|
1594
|
+
threshold: 5,
|
|
1595
|
+
getTool,
|
|
1596
|
+
onClickDetected: (pos, tool) => {
|
|
1597
|
+
var _a;
|
|
1598
|
+
const defaults = getDefaults();
|
|
1599
|
+
if (!defaults) return;
|
|
1600
|
+
const clickConfig = tool.clickBehavior;
|
|
1601
|
+
if (!(clickConfig == null ? void 0 : clickConfig.enabled)) return;
|
|
1602
|
+
const { width, height } = clickConfig.defaultSize;
|
|
1603
|
+
const rect = {
|
|
1604
|
+
origin: { x: pos.x - width / 2, y: pos.y - height / 2 },
|
|
1605
|
+
size: { width, height }
|
|
1606
|
+
};
|
|
1607
|
+
const contents = clickConfig.defaultContent ?? defaults.contents;
|
|
1608
|
+
let anno = {
|
|
1609
|
+
...defaults,
|
|
1610
|
+
contents,
|
|
1611
|
+
type: PdfAnnotationSubtype.FREETEXT,
|
|
1612
|
+
rect,
|
|
1613
|
+
pageIndex,
|
|
1614
|
+
id: uuidV4(),
|
|
1615
|
+
created: /* @__PURE__ */ new Date()
|
|
1616
|
+
};
|
|
1617
|
+
if ((_a = tool.behavior) == null ? void 0 : _a.insertUpright) {
|
|
1618
|
+
anno = applyInsertUpright(anno, pageRotation, false);
|
|
1619
|
+
}
|
|
1620
|
+
anno = clampAnnotationToPage(anno, pageSize);
|
|
1621
|
+
onCommit(anno);
|
|
1622
|
+
}
|
|
1623
|
+
});
|
|
1624
|
+
const getPreview = (current) => {
|
|
1625
|
+
const start = getStart();
|
|
1626
|
+
if (!start) return null;
|
|
1627
|
+
const defaults = getDefaults();
|
|
1628
|
+
if (!defaults) return null;
|
|
1629
|
+
const minX = Math.min(start.x, current.x);
|
|
1630
|
+
const minY = Math.min(start.y, current.y);
|
|
1631
|
+
const width = Math.abs(start.x - current.x);
|
|
1632
|
+
const height = Math.abs(start.y - current.y);
|
|
1633
|
+
const rect = {
|
|
1634
|
+
origin: { x: minX, y: minY },
|
|
1635
|
+
size: { width, height }
|
|
1636
|
+
};
|
|
1637
|
+
return {
|
|
1638
|
+
type: PdfAnnotationSubtype.FREETEXT,
|
|
1639
|
+
bounds: rect,
|
|
1640
|
+
data: {
|
|
1641
|
+
...defaults,
|
|
1642
|
+
rect
|
|
1643
|
+
}
|
|
1644
|
+
};
|
|
1645
|
+
};
|
|
1646
|
+
return {
|
|
1647
|
+
onPointerDown: (pos, evt) => {
|
|
1648
|
+
var _a;
|
|
1649
|
+
const clampedPos = clampToPage(pos);
|
|
1650
|
+
setStart(clampedPos);
|
|
1651
|
+
clickDetector.onStart(clampedPos);
|
|
1652
|
+
onPreview(getPreview(clampedPos));
|
|
1653
|
+
(_a = evt.setPointerCapture) == null ? void 0 : _a.call(evt);
|
|
1654
|
+
},
|
|
1655
|
+
onPointerMove: (pos) => {
|
|
1656
|
+
const clampedPos = clampToPage(pos);
|
|
1657
|
+
clickDetector.onMove(clampedPos);
|
|
1658
|
+
if (getStart() && clickDetector.hasMoved()) {
|
|
1659
|
+
onPreview(getPreview(clampedPos));
|
|
1660
|
+
}
|
|
1661
|
+
},
|
|
1662
|
+
onPointerUp: (pos, evt) => {
|
|
1663
|
+
var _a, _b;
|
|
1664
|
+
const start = getStart();
|
|
1665
|
+
if (!start) return;
|
|
1666
|
+
const defaults = getDefaults();
|
|
1667
|
+
if (!defaults) return;
|
|
1668
|
+
const clampedPos = clampToPage(pos);
|
|
1669
|
+
if (!clickDetector.hasMoved()) {
|
|
1670
|
+
clickDetector.onEnd(clampedPos);
|
|
1671
|
+
} else {
|
|
1672
|
+
const minX = Math.min(start.x, clampedPos.x);
|
|
1673
|
+
const minY = Math.min(start.y, clampedPos.y);
|
|
1674
|
+
const width = Math.abs(start.x - clampedPos.x);
|
|
1675
|
+
const height = Math.abs(start.y - clampedPos.y);
|
|
1676
|
+
const rect = {
|
|
1677
|
+
origin: { x: minX, y: minY },
|
|
1678
|
+
size: { width, height }
|
|
1679
|
+
};
|
|
1680
|
+
const tool = getTool();
|
|
1681
|
+
let anno = {
|
|
1682
|
+
...defaults,
|
|
1683
|
+
type: PdfAnnotationSubtype.FREETEXT,
|
|
1684
|
+
rect,
|
|
1685
|
+
pageIndex: context.pageIndex,
|
|
1686
|
+
id: uuidV4(),
|
|
1687
|
+
created: /* @__PURE__ */ new Date()
|
|
1688
|
+
};
|
|
1689
|
+
if ((_a = tool == null ? void 0 : tool.behavior) == null ? void 0 : _a.insertUpright) {
|
|
1690
|
+
anno = applyInsertUpright(anno, pageRotation, true);
|
|
1691
|
+
}
|
|
1692
|
+
onCommit(anno);
|
|
1693
|
+
}
|
|
1694
|
+
setStart(null);
|
|
1695
|
+
onPreview(null);
|
|
1696
|
+
clickDetector.reset();
|
|
1697
|
+
(_b = evt.releasePointerCapture) == null ? void 0 : _b.call(evt);
|
|
1698
|
+
},
|
|
1699
|
+
onPointerLeave: (_, evt) => {
|
|
1700
|
+
var _a;
|
|
1701
|
+
setStart(null);
|
|
1702
|
+
onPreview(null);
|
|
1703
|
+
clickDetector.reset();
|
|
1704
|
+
(_a = evt.releasePointerCapture) == null ? void 0 : _a.call(evt);
|
|
1705
|
+
},
|
|
1706
|
+
onPointerCancel: (_, evt) => {
|
|
1707
|
+
var _a;
|
|
1708
|
+
setStart(null);
|
|
1709
|
+
onPreview(null);
|
|
1710
|
+
clickDetector.reset();
|
|
1711
|
+
(_a = evt.releasePointerCapture) == null ? void 0 : _a.call(evt);
|
|
1712
|
+
}
|
|
1713
|
+
};
|
|
1714
|
+
}
|
|
1715
|
+
};
|
|
1450
1716
|
const lineHandlerFactory = {
|
|
1451
1717
|
annotationType: PdfAnnotationSubtype.LINE,
|
|
1452
1718
|
create(context) {
|
|
@@ -1953,22 +2219,19 @@ const squareHandlerFactory = {
|
|
|
1953
2219
|
const stampHandlerFactory = {
|
|
1954
2220
|
annotationType: PdfAnnotationSubtype.STAMP,
|
|
1955
2221
|
create(context) {
|
|
1956
|
-
const { services, onCommit, getTool, pageSize } = context;
|
|
2222
|
+
const { services, onCommit, getTool, pageSize, pageRotation } = context;
|
|
1957
2223
|
return {
|
|
1958
2224
|
onPointerDown: (pos) => {
|
|
1959
2225
|
const tool = getTool();
|
|
1960
2226
|
if (!tool) return;
|
|
1961
2227
|
const { imageSrc, imageSize } = tool.defaults;
|
|
1962
2228
|
const placeStamp = (imageData, width, height) => {
|
|
1963
|
-
|
|
1964
|
-
const originY = pos.y - height / 2;
|
|
1965
|
-
const finalX = clamp(originX, 0, pageSize.width - width);
|
|
1966
|
-
const finalY = clamp(originY, 0, pageSize.height - height);
|
|
2229
|
+
var _a;
|
|
1967
2230
|
const rect = {
|
|
1968
|
-
origin: { x:
|
|
2231
|
+
origin: { x: pos.x - width / 2, y: pos.y - height / 2 },
|
|
1969
2232
|
size: { width, height }
|
|
1970
2233
|
};
|
|
1971
|
-
|
|
2234
|
+
let anno = {
|
|
1972
2235
|
...tool.defaults,
|
|
1973
2236
|
rect,
|
|
1974
2237
|
type: PdfAnnotationSubtype.STAMP,
|
|
@@ -1979,6 +2242,10 @@ const stampHandlerFactory = {
|
|
|
1979
2242
|
id: uuidV4(),
|
|
1980
2243
|
created: /* @__PURE__ */ new Date()
|
|
1981
2244
|
};
|
|
2245
|
+
if ((_a = tool.behavior) == null ? void 0 : _a.insertUpright) {
|
|
2246
|
+
anno = applyInsertUpright(anno, pageRotation, false);
|
|
2247
|
+
}
|
|
2248
|
+
anno = clampAnnotationToPage(anno, pageSize);
|
|
1982
2249
|
onCommit(anno, { imageData });
|
|
1983
2250
|
};
|
|
1984
2251
|
if (imageSrc) {
|
|
@@ -2149,322 +2416,424 @@ const circleHandlerFactory = {
|
|
|
2149
2416
|
}
|
|
2150
2417
|
};
|
|
2151
2418
|
}
|
|
2152
|
-
};
|
|
2153
|
-
const patchInk = (original, ctx) => {
|
|
2154
|
-
|
|
2155
|
-
|
|
2156
|
-
case "vertex-edit":
|
|
2157
|
-
return ctx.changes;
|
|
2158
|
-
case "move":
|
|
2159
|
-
if (ctx.changes.rect) {
|
|
2160
|
-
const dx = ctx.changes.rect.origin.x - original.rect.origin.x;
|
|
2161
|
-
const dy = ctx.changes.rect.origin.y - original.rect.origin.y;
|
|
2162
|
-
const movedInkList = original.inkList.map((stroke) => ({
|
|
2163
|
-
points: stroke.points.map((p) => ({
|
|
2164
|
-
x: p.x + dx,
|
|
2165
|
-
y: p.y + dy
|
|
2166
|
-
}))
|
|
2167
|
-
}));
|
|
2168
|
-
return {
|
|
2169
|
-
rect: ctx.changes.rect,
|
|
2170
|
-
inkList: movedInkList
|
|
2171
|
-
};
|
|
2172
|
-
}
|
|
2419
|
+
};
|
|
2420
|
+
const patchInk = (original, ctx) => {
|
|
2421
|
+
switch (ctx.type) {
|
|
2422
|
+
case "vertex-edit":
|
|
2173
2423
|
return ctx.changes;
|
|
2174
|
-
case "
|
|
2175
|
-
if (ctx.changes.rect)
|
|
2176
|
-
|
|
2177
|
-
|
|
2178
|
-
|
|
2179
|
-
|
|
2180
|
-
|
|
2181
|
-
|
|
2182
|
-
|
|
2183
|
-
|
|
2184
|
-
|
|
2185
|
-
|
|
2186
|
-
|
|
2187
|
-
|
|
2188
|
-
|
|
2189
|
-
|
|
2190
|
-
|
|
2191
|
-
|
|
2192
|
-
|
|
2193
|
-
|
|
2194
|
-
|
|
2195
|
-
|
|
2196
|
-
ctx.changes.rect.size = {
|
|
2197
|
-
width: oldRect.size.width * minScale,
|
|
2198
|
-
height: oldRect.size.height * minScale
|
|
2199
|
-
};
|
|
2424
|
+
case "move": {
|
|
2425
|
+
if (!ctx.changes.rect) return ctx.changes;
|
|
2426
|
+
const { dx, dy, rects } = baseMoveChanges(original, ctx.changes.rect);
|
|
2427
|
+
return {
|
|
2428
|
+
...rects,
|
|
2429
|
+
inkList: original.inkList.map((stroke) => ({
|
|
2430
|
+
points: stroke.points.map((p) => ({ x: p.x + dx, y: p.y + dy }))
|
|
2431
|
+
}))
|
|
2432
|
+
};
|
|
2433
|
+
}
|
|
2434
|
+
case "resize": {
|
|
2435
|
+
if (!ctx.changes.rect) return ctx.changes;
|
|
2436
|
+
const { oldRect, resolvedRect, rects } = baseResizeScaling(
|
|
2437
|
+
original,
|
|
2438
|
+
ctx.changes.rect,
|
|
2439
|
+
ctx.metadata
|
|
2440
|
+
);
|
|
2441
|
+
const inset = (r, pad) => ({
|
|
2442
|
+
origin: { x: r.origin.x + pad, y: r.origin.y + pad },
|
|
2443
|
+
size: {
|
|
2444
|
+
width: Math.max(1, r.size.width - pad * 2),
|
|
2445
|
+
height: Math.max(1, r.size.height - pad * 2)
|
|
2200
2446
|
}
|
|
2201
|
-
|
|
2202
|
-
|
|
2203
|
-
|
|
2204
|
-
|
|
2205
|
-
|
|
2206
|
-
|
|
2207
|
-
|
|
2208
|
-
|
|
2209
|
-
|
|
2210
|
-
|
|
2211
|
-
|
|
2212
|
-
|
|
2213
|
-
|
|
2214
|
-
const innerNew = inset(ctx.changes.rect, newStrokeWidth / 2);
|
|
2215
|
-
const sx = innerNew.size.width / Math.max(innerOld.size.width, 1e-6);
|
|
2216
|
-
const sy = innerNew.size.height / Math.max(innerOld.size.height, 1e-6);
|
|
2217
|
-
const newInkList = original.inkList.map((stroke) => ({
|
|
2447
|
+
});
|
|
2448
|
+
const strokeScale = Math.min(
|
|
2449
|
+
resolvedRect.size.width / oldRect.size.width,
|
|
2450
|
+
resolvedRect.size.height / oldRect.size.height
|
|
2451
|
+
);
|
|
2452
|
+
const newStrokeWidth = Math.max(1, Math.round(original.strokeWidth * strokeScale));
|
|
2453
|
+
const innerOld = inset(oldRect, original.strokeWidth / 2);
|
|
2454
|
+
const innerNew = inset(resolvedRect, newStrokeWidth / 2);
|
|
2455
|
+
const sx = innerNew.size.width / Math.max(innerOld.size.width, 1e-6);
|
|
2456
|
+
const sy = innerNew.size.height / Math.max(innerOld.size.height, 1e-6);
|
|
2457
|
+
return {
|
|
2458
|
+
...rects,
|
|
2459
|
+
inkList: original.inkList.map((stroke) => ({
|
|
2218
2460
|
points: stroke.points.map((p) => ({
|
|
2219
2461
|
x: innerNew.origin.x + (p.x - innerOld.origin.x) * sx,
|
|
2220
2462
|
y: innerNew.origin.y + (p.y - innerOld.origin.y) * sy
|
|
2221
2463
|
}))
|
|
2222
|
-
}))
|
|
2464
|
+
})),
|
|
2465
|
+
strokeWidth: newStrokeWidth
|
|
2466
|
+
};
|
|
2467
|
+
}
|
|
2468
|
+
case "rotate": {
|
|
2469
|
+
const result = baseRotateChanges(original, ctx);
|
|
2470
|
+
if (!result) return ctx.changes;
|
|
2471
|
+
const { dx, dy } = rotateOrbitDelta(original, result);
|
|
2472
|
+
return {
|
|
2473
|
+
...result,
|
|
2474
|
+
inkList: original.inkList.map((stroke) => ({
|
|
2475
|
+
points: stroke.points.map((p) => ({ x: p.x + dx, y: p.y + dy }))
|
|
2476
|
+
}))
|
|
2477
|
+
};
|
|
2478
|
+
}
|
|
2479
|
+
case "property-update": {
|
|
2480
|
+
const needsRectUpdate = ctx.changes.strokeWidth !== void 0 || ctx.changes.rotation !== void 0;
|
|
2481
|
+
if (!needsRectUpdate) return ctx.changes;
|
|
2482
|
+
const merged = { ...original, ...ctx.changes };
|
|
2483
|
+
const pts = merged.inkList.flatMap((s) => s.points);
|
|
2484
|
+
const tightRect = expandRect(rectFromPoints(pts), merged.strokeWidth / 2);
|
|
2485
|
+
const effectiveRotation = ctx.changes.rotation ?? original.rotation ?? 0;
|
|
2486
|
+
if (original.unrotatedRect || ctx.changes.rotation !== void 0) {
|
|
2223
2487
|
return {
|
|
2224
|
-
|
|
2225
|
-
|
|
2226
|
-
|
|
2488
|
+
...ctx.changes,
|
|
2489
|
+
unrotatedRect: tightRect,
|
|
2490
|
+
rect: calculateRotatedRectAABBAroundPoint(
|
|
2491
|
+
tightRect,
|
|
2492
|
+
effectiveRotation,
|
|
2493
|
+
resolveAnnotationRotationCenter(original)
|
|
2494
|
+
)
|
|
2227
2495
|
};
|
|
2228
2496
|
}
|
|
2229
|
-
return ctx.changes;
|
|
2230
|
-
|
|
2231
|
-
if (ctx.changes.strokeWidth !== void 0) {
|
|
2232
|
-
const merged = { ...original, ...ctx.changes };
|
|
2233
|
-
const pts = merged.inkList.flatMap((s) => s.points);
|
|
2234
|
-
const rect = expandRect(rectFromPoints(pts), merged.strokeWidth / 2);
|
|
2235
|
-
return { ...ctx.changes, rect };
|
|
2236
|
-
}
|
|
2237
|
-
return ctx.changes;
|
|
2497
|
+
return { ...ctx.changes, rect: tightRect };
|
|
2498
|
+
}
|
|
2238
2499
|
default:
|
|
2239
2500
|
return ctx.changes;
|
|
2240
2501
|
}
|
|
2241
2502
|
};
|
|
2242
2503
|
const patchLine = (orig, ctx) => {
|
|
2243
|
-
var _a;
|
|
2244
2504
|
switch (ctx.type) {
|
|
2245
2505
|
case "vertex-edit":
|
|
2246
2506
|
if (ctx.changes.linePoints) {
|
|
2247
2507
|
const { start, end } = ctx.changes.linePoints;
|
|
2248
|
-
const
|
|
2249
|
-
|
|
2250
|
-
|
|
2251
|
-
|
|
2252
|
-
};
|
|
2253
|
-
}
|
|
2254
|
-
return ctx.changes;
|
|
2255
|
-
case "move":
|
|
2256
|
-
if (ctx.changes.rect) {
|
|
2257
|
-
const dx = ctx.changes.rect.origin.x - orig.rect.origin.x;
|
|
2258
|
-
const dy = ctx.changes.rect.origin.y - orig.rect.origin.y;
|
|
2508
|
+
const rawPoints = [start, end];
|
|
2509
|
+
const rawRect = lineRectWithEndings(rawPoints, orig.strokeWidth, orig.lineEndings);
|
|
2510
|
+
const compensated = compensateRotatedVertexEdit(orig, rawPoints, rawRect);
|
|
2511
|
+
const rect = lineRectWithEndings(compensated, orig.strokeWidth, orig.lineEndings);
|
|
2259
2512
|
return {
|
|
2260
|
-
|
|
2261
|
-
linePoints: {
|
|
2262
|
-
start: { x: orig.linePoints.start.x + dx, y: orig.linePoints.start.y + dy },
|
|
2263
|
-
end: { x: orig.linePoints.end.x + dx, y: orig.linePoints.end.y + dy }
|
|
2264
|
-
}
|
|
2513
|
+
...resolveVertexEditRects(orig, rect),
|
|
2514
|
+
linePoints: { start: compensated[0], end: compensated[1] }
|
|
2265
2515
|
};
|
|
2266
2516
|
}
|
|
2267
2517
|
return ctx.changes;
|
|
2268
|
-
case "
|
|
2269
|
-
if (ctx.changes.rect)
|
|
2270
|
-
|
|
2271
|
-
|
|
2272
|
-
|
|
2273
|
-
|
|
2274
|
-
|
|
2275
|
-
|
|
2276
|
-
scaleX = Math.max(scaleX, minSize / oldRect.size.width);
|
|
2277
|
-
scaleY = Math.max(scaleY, minSize / oldRect.size.height);
|
|
2278
|
-
ctx.changes.rect = {
|
|
2279
|
-
origin: newRect.origin,
|
|
2280
|
-
size: {
|
|
2281
|
-
width: oldRect.size.width * scaleX,
|
|
2282
|
-
height: oldRect.size.height * scaleY
|
|
2283
|
-
}
|
|
2284
|
-
};
|
|
2285
|
-
}
|
|
2286
|
-
if ((_a = ctx.metadata) == null ? void 0 : _a.maintainAspectRatio) {
|
|
2287
|
-
const minScale = Math.min(scaleX, scaleY);
|
|
2288
|
-
scaleX = minScale;
|
|
2289
|
-
scaleY = minScale;
|
|
2290
|
-
ctx.changes.rect.size = {
|
|
2291
|
-
width: oldRect.size.width * minScale,
|
|
2292
|
-
height: oldRect.size.height * minScale
|
|
2293
|
-
};
|
|
2518
|
+
case "move": {
|
|
2519
|
+
if (!ctx.changes.rect) return ctx.changes;
|
|
2520
|
+
const { dx, dy, rects } = baseMoveChanges(orig, ctx.changes.rect);
|
|
2521
|
+
return {
|
|
2522
|
+
...rects,
|
|
2523
|
+
linePoints: {
|
|
2524
|
+
start: { x: orig.linePoints.start.x + dx, y: orig.linePoints.start.y + dy },
|
|
2525
|
+
end: { x: orig.linePoints.end.x + dx, y: orig.linePoints.end.y + dy }
|
|
2294
2526
|
}
|
|
2295
|
-
|
|
2527
|
+
};
|
|
2528
|
+
}
|
|
2529
|
+
case "resize": {
|
|
2530
|
+
if (!ctx.changes.rect) return ctx.changes;
|
|
2531
|
+
const { scaleX, scaleY, oldRect, resolvedRect, rects } = baseResizeScaling(
|
|
2532
|
+
orig,
|
|
2533
|
+
ctx.changes.rect,
|
|
2534
|
+
ctx.metadata
|
|
2535
|
+
);
|
|
2536
|
+
return {
|
|
2537
|
+
...rects,
|
|
2538
|
+
linePoints: {
|
|
2296
2539
|
start: {
|
|
2297
|
-
x:
|
|
2298
|
-
y:
|
|
2540
|
+
x: resolvedRect.origin.x + (orig.linePoints.start.x - oldRect.origin.x) * scaleX,
|
|
2541
|
+
y: resolvedRect.origin.y + (orig.linePoints.start.y - oldRect.origin.y) * scaleY
|
|
2299
2542
|
},
|
|
2300
2543
|
end: {
|
|
2301
|
-
x:
|
|
2302
|
-
y:
|
|
2544
|
+
x: resolvedRect.origin.x + (orig.linePoints.end.x - oldRect.origin.x) * scaleX,
|
|
2545
|
+
y: resolvedRect.origin.y + (orig.linePoints.end.y - oldRect.origin.y) * scaleY
|
|
2303
2546
|
}
|
|
2304
|
-
}
|
|
2547
|
+
}
|
|
2548
|
+
};
|
|
2549
|
+
}
|
|
2550
|
+
case "rotate": {
|
|
2551
|
+
const result = baseRotateChanges(orig, ctx);
|
|
2552
|
+
if (!result) return ctx.changes;
|
|
2553
|
+
const { dx, dy } = rotateOrbitDelta(orig, result);
|
|
2554
|
+
return {
|
|
2555
|
+
...result,
|
|
2556
|
+
linePoints: {
|
|
2557
|
+
start: { x: orig.linePoints.start.x + dx, y: orig.linePoints.start.y + dy },
|
|
2558
|
+
end: { x: orig.linePoints.end.x + dx, y: orig.linePoints.end.y + dy }
|
|
2559
|
+
}
|
|
2560
|
+
};
|
|
2561
|
+
}
|
|
2562
|
+
case "property-update": {
|
|
2563
|
+
const needsRectUpdate = ctx.changes.strokeWidth !== void 0 || ctx.changes.lineEndings !== void 0 || ctx.changes.rotation !== void 0;
|
|
2564
|
+
if (!needsRectUpdate) return ctx.changes;
|
|
2565
|
+
const merged = { ...orig, ...ctx.changes };
|
|
2566
|
+
const tightRect = lineRectWithEndings(
|
|
2567
|
+
[merged.linePoints.start, merged.linePoints.end],
|
|
2568
|
+
merged.strokeWidth,
|
|
2569
|
+
merged.lineEndings
|
|
2570
|
+
);
|
|
2571
|
+
const effectiveRotation = ctx.changes.rotation ?? orig.rotation ?? 0;
|
|
2572
|
+
if (orig.unrotatedRect || ctx.changes.rotation !== void 0) {
|
|
2305
2573
|
return {
|
|
2306
|
-
|
|
2307
|
-
|
|
2574
|
+
...ctx.changes,
|
|
2575
|
+
unrotatedRect: tightRect,
|
|
2576
|
+
rect: calculateRotatedRectAABBAroundPoint(
|
|
2577
|
+
tightRect,
|
|
2578
|
+
effectiveRotation,
|
|
2579
|
+
resolveAnnotationRotationCenter(orig)
|
|
2580
|
+
)
|
|
2308
2581
|
};
|
|
2309
2582
|
}
|
|
2310
|
-
return ctx.changes;
|
|
2311
|
-
|
|
2312
|
-
if (ctx.changes.strokeWidth || ctx.changes.lineEndings) {
|
|
2313
|
-
const merged = { ...orig, ...ctx.changes };
|
|
2314
|
-
const rect = lineRectWithEndings(
|
|
2315
|
-
[merged.linePoints.start, merged.linePoints.end],
|
|
2316
|
-
merged.strokeWidth,
|
|
2317
|
-
merged.lineEndings
|
|
2318
|
-
);
|
|
2319
|
-
return { ...ctx.changes, rect };
|
|
2320
|
-
}
|
|
2321
|
-
return ctx.changes;
|
|
2583
|
+
return { ...ctx.changes, rect: tightRect };
|
|
2584
|
+
}
|
|
2322
2585
|
default:
|
|
2323
2586
|
return ctx.changes;
|
|
2324
2587
|
}
|
|
2325
2588
|
};
|
|
2326
2589
|
const patchPolyline = (orig, ctx) => {
|
|
2327
|
-
var _a;
|
|
2328
2590
|
switch (ctx.type) {
|
|
2329
2591
|
case "vertex-edit":
|
|
2330
2592
|
if (ctx.changes.vertices && ctx.changes.vertices.length) {
|
|
2593
|
+
const rawVertices = ctx.changes.vertices;
|
|
2594
|
+
const rawRect = lineRectWithEndings(rawVertices, orig.strokeWidth, orig.lineEndings);
|
|
2595
|
+
const compensated = compensateRotatedVertexEdit(orig, rawVertices, rawRect);
|
|
2596
|
+
const rect = lineRectWithEndings(compensated, orig.strokeWidth, orig.lineEndings);
|
|
2331
2597
|
return {
|
|
2332
|
-
|
|
2333
|
-
vertices:
|
|
2334
|
-
};
|
|
2335
|
-
}
|
|
2336
|
-
return ctx.changes;
|
|
2337
|
-
case "move":
|
|
2338
|
-
if (ctx.changes.rect) {
|
|
2339
|
-
const dx = ctx.changes.rect.origin.x - orig.rect.origin.x;
|
|
2340
|
-
const dy = ctx.changes.rect.origin.y - orig.rect.origin.y;
|
|
2341
|
-
const moved = orig.vertices.map((p) => ({ x: p.x + dx, y: p.y + dy }));
|
|
2342
|
-
return {
|
|
2343
|
-
rect: ctx.changes.rect,
|
|
2344
|
-
vertices: moved
|
|
2598
|
+
...resolveVertexEditRects(orig, rect),
|
|
2599
|
+
vertices: compensated
|
|
2345
2600
|
};
|
|
2346
2601
|
}
|
|
2347
2602
|
return ctx.changes;
|
|
2348
|
-
case "
|
|
2349
|
-
if (ctx.changes.rect)
|
|
2350
|
-
|
|
2351
|
-
|
|
2352
|
-
|
|
2353
|
-
|
|
2354
|
-
|
|
2355
|
-
|
|
2356
|
-
|
|
2357
|
-
|
|
2358
|
-
|
|
2359
|
-
|
|
2360
|
-
|
|
2361
|
-
|
|
2362
|
-
|
|
2363
|
-
|
|
2364
|
-
|
|
2365
|
-
|
|
2366
|
-
|
|
2367
|
-
|
|
2368
|
-
|
|
2369
|
-
|
|
2370
|
-
|
|
2371
|
-
|
|
2372
|
-
|
|
2373
|
-
|
|
2374
|
-
|
|
2375
|
-
|
|
2376
|
-
|
|
2377
|
-
|
|
2378
|
-
|
|
2603
|
+
case "move": {
|
|
2604
|
+
if (!ctx.changes.rect) return ctx.changes;
|
|
2605
|
+
const { dx, dy, rects } = baseMoveChanges(orig, ctx.changes.rect);
|
|
2606
|
+
return {
|
|
2607
|
+
...rects,
|
|
2608
|
+
vertices: orig.vertices.map((p) => ({ x: p.x + dx, y: p.y + dy }))
|
|
2609
|
+
};
|
|
2610
|
+
}
|
|
2611
|
+
case "resize": {
|
|
2612
|
+
if (!ctx.changes.rect) return ctx.changes;
|
|
2613
|
+
const { scaleX, scaleY, oldRect, resolvedRect, rects } = baseResizeScaling(
|
|
2614
|
+
orig,
|
|
2615
|
+
ctx.changes.rect,
|
|
2616
|
+
ctx.metadata
|
|
2617
|
+
);
|
|
2618
|
+
return {
|
|
2619
|
+
...rects,
|
|
2620
|
+
vertices: orig.vertices.map((v) => ({
|
|
2621
|
+
x: resolvedRect.origin.x + (v.x - oldRect.origin.x) * scaleX,
|
|
2622
|
+
y: resolvedRect.origin.y + (v.y - oldRect.origin.y) * scaleY
|
|
2623
|
+
}))
|
|
2624
|
+
};
|
|
2625
|
+
}
|
|
2626
|
+
case "rotate": {
|
|
2627
|
+
const result = baseRotateChanges(orig, ctx);
|
|
2628
|
+
if (!result) return ctx.changes;
|
|
2629
|
+
const { dx, dy } = rotateOrbitDelta(orig, result);
|
|
2630
|
+
return {
|
|
2631
|
+
...result,
|
|
2632
|
+
vertices: orig.vertices.map((v) => ({ x: v.x + dx, y: v.y + dy }))
|
|
2633
|
+
};
|
|
2634
|
+
}
|
|
2635
|
+
case "property-update": {
|
|
2636
|
+
const needsRectUpdate = ctx.changes.strokeWidth !== void 0 || ctx.changes.lineEndings !== void 0 || ctx.changes.rotation !== void 0;
|
|
2637
|
+
if (!needsRectUpdate) return ctx.changes;
|
|
2638
|
+
const merged = { ...orig, ...ctx.changes };
|
|
2639
|
+
const tightRect = lineRectWithEndings(
|
|
2640
|
+
merged.vertices,
|
|
2641
|
+
merged.strokeWidth,
|
|
2642
|
+
merged.lineEndings
|
|
2643
|
+
);
|
|
2644
|
+
const effectiveRotation = ctx.changes.rotation ?? orig.rotation ?? 0;
|
|
2645
|
+
if (orig.unrotatedRect || ctx.changes.rotation !== void 0) {
|
|
2379
2646
|
return {
|
|
2380
|
-
|
|
2381
|
-
|
|
2647
|
+
...ctx.changes,
|
|
2648
|
+
unrotatedRect: tightRect,
|
|
2649
|
+
rect: calculateRotatedRectAABBAroundPoint(
|
|
2650
|
+
tightRect,
|
|
2651
|
+
effectiveRotation,
|
|
2652
|
+
resolveAnnotationRotationCenter(orig)
|
|
2653
|
+
)
|
|
2382
2654
|
};
|
|
2383
2655
|
}
|
|
2384
|
-
return ctx.changes;
|
|
2385
|
-
|
|
2386
|
-
if (ctx.changes.strokeWidth !== void 0 || ctx.changes.lineEndings !== void 0) {
|
|
2387
|
-
const merged = { ...orig, ...ctx.changes };
|
|
2388
|
-
const rect = lineRectWithEndings(merged.vertices, merged.strokeWidth, merged.lineEndings);
|
|
2389
|
-
return { ...ctx.changes, rect };
|
|
2390
|
-
}
|
|
2391
|
-
return ctx.changes;
|
|
2656
|
+
return { ...ctx.changes, rect: tightRect };
|
|
2657
|
+
}
|
|
2392
2658
|
default:
|
|
2393
2659
|
return ctx.changes;
|
|
2394
2660
|
}
|
|
2395
2661
|
};
|
|
2396
2662
|
const patchPolygon = (orig, ctx) => {
|
|
2397
|
-
var _a;
|
|
2398
2663
|
switch (ctx.type) {
|
|
2399
2664
|
case "vertex-edit":
|
|
2400
2665
|
if (ctx.changes.vertices && ctx.changes.vertices.length) {
|
|
2401
2666
|
const pad = orig.strokeWidth / 2;
|
|
2667
|
+
const rawVertices = ctx.changes.vertices;
|
|
2668
|
+
const rawRect = expandRect(rectFromPoints(rawVertices), pad);
|
|
2669
|
+
const compensated = compensateRotatedVertexEdit(orig, rawVertices, rawRect);
|
|
2670
|
+
const rect = expandRect(rectFromPoints(compensated), pad);
|
|
2402
2671
|
return {
|
|
2403
|
-
|
|
2404
|
-
vertices:
|
|
2672
|
+
...resolveVertexEditRects(orig, rect),
|
|
2673
|
+
vertices: compensated
|
|
2405
2674
|
};
|
|
2406
2675
|
}
|
|
2407
2676
|
return ctx.changes;
|
|
2408
|
-
case "move":
|
|
2409
|
-
if (ctx.changes.rect)
|
|
2410
|
-
|
|
2411
|
-
|
|
2412
|
-
|
|
2677
|
+
case "move": {
|
|
2678
|
+
if (!ctx.changes.rect) return ctx.changes;
|
|
2679
|
+
const { dx, dy, rects } = baseMoveChanges(orig, ctx.changes.rect);
|
|
2680
|
+
return {
|
|
2681
|
+
...rects,
|
|
2682
|
+
vertices: orig.vertices.map((p) => ({ x: p.x + dx, y: p.y + dy }))
|
|
2683
|
+
};
|
|
2684
|
+
}
|
|
2685
|
+
case "resize": {
|
|
2686
|
+
if (!ctx.changes.rect) return ctx.changes;
|
|
2687
|
+
const { scaleX, scaleY, oldRect, resolvedRect, rects } = baseResizeScaling(
|
|
2688
|
+
orig,
|
|
2689
|
+
ctx.changes.rect,
|
|
2690
|
+
ctx.metadata
|
|
2691
|
+
);
|
|
2692
|
+
return {
|
|
2693
|
+
...rects,
|
|
2694
|
+
vertices: orig.vertices.map((v) => ({
|
|
2695
|
+
x: resolvedRect.origin.x + (v.x - oldRect.origin.x) * scaleX,
|
|
2696
|
+
y: resolvedRect.origin.y + (v.y - oldRect.origin.y) * scaleY
|
|
2697
|
+
}))
|
|
2698
|
+
};
|
|
2699
|
+
}
|
|
2700
|
+
case "rotate": {
|
|
2701
|
+
const result = baseRotateChanges(orig, ctx);
|
|
2702
|
+
if (!result) return ctx.changes;
|
|
2703
|
+
const { dx, dy } = rotateOrbitDelta(orig, result);
|
|
2704
|
+
return {
|
|
2705
|
+
...result,
|
|
2706
|
+
vertices: orig.vertices.map((v) => ({ x: v.x + dx, y: v.y + dy }))
|
|
2707
|
+
};
|
|
2708
|
+
}
|
|
2709
|
+
case "property-update": {
|
|
2710
|
+
const needsRectUpdate = ctx.changes.strokeWidth !== void 0 || ctx.changes.rotation !== void 0;
|
|
2711
|
+
if (!needsRectUpdate) return ctx.changes;
|
|
2712
|
+
const merged = { ...orig, ...ctx.changes };
|
|
2713
|
+
const pad = merged.strokeWidth / 2;
|
|
2714
|
+
const tightRect = expandRect(rectFromPoints(merged.vertices), pad);
|
|
2715
|
+
const effectiveRotation = ctx.changes.rotation ?? orig.rotation ?? 0;
|
|
2716
|
+
if (orig.unrotatedRect || ctx.changes.rotation !== void 0) {
|
|
2413
2717
|
return {
|
|
2414
|
-
|
|
2415
|
-
|
|
2718
|
+
...ctx.changes,
|
|
2719
|
+
unrotatedRect: tightRect,
|
|
2720
|
+
rect: calculateRotatedRectAABBAroundPoint(
|
|
2721
|
+
tightRect,
|
|
2722
|
+
effectiveRotation,
|
|
2723
|
+
resolveAnnotationRotationCenter(orig)
|
|
2724
|
+
)
|
|
2416
2725
|
};
|
|
2417
2726
|
}
|
|
2727
|
+
return { ...ctx.changes, rect: tightRect };
|
|
2728
|
+
}
|
|
2729
|
+
default:
|
|
2418
2730
|
return ctx.changes;
|
|
2731
|
+
}
|
|
2732
|
+
};
|
|
2733
|
+
const patchCircle = (orig, ctx) => {
|
|
2734
|
+
switch (ctx.type) {
|
|
2735
|
+
case "move":
|
|
2736
|
+
if (!ctx.changes.rect) return ctx.changes;
|
|
2737
|
+
return baseMoveChanges(orig, ctx.changes.rect).rects;
|
|
2419
2738
|
case "resize":
|
|
2420
|
-
if (ctx.changes.rect)
|
|
2421
|
-
|
|
2422
|
-
|
|
2423
|
-
|
|
2424
|
-
|
|
2425
|
-
|
|
2426
|
-
|
|
2427
|
-
|
|
2428
|
-
|
|
2429
|
-
|
|
2430
|
-
|
|
2431
|
-
|
|
2432
|
-
|
|
2433
|
-
|
|
2434
|
-
|
|
2435
|
-
|
|
2436
|
-
|
|
2437
|
-
|
|
2438
|
-
|
|
2439
|
-
|
|
2440
|
-
|
|
2441
|
-
|
|
2442
|
-
|
|
2443
|
-
|
|
2444
|
-
|
|
2445
|
-
}
|
|
2446
|
-
const scaledVertices = orig.vertices.map((vertex) => ({
|
|
2447
|
-
x: ctx.changes.rect.origin.x + (vertex.x - oldRect.origin.x) * scaleX,
|
|
2448
|
-
y: ctx.changes.rect.origin.y + (vertex.y - oldRect.origin.y) * scaleY
|
|
2449
|
-
}));
|
|
2450
|
-
return {
|
|
2451
|
-
rect: ctx.changes.rect,
|
|
2452
|
-
vertices: scaledVertices
|
|
2453
|
-
};
|
|
2739
|
+
if (!ctx.changes.rect) return ctx.changes;
|
|
2740
|
+
return baseResizeScaling(orig, ctx.changes.rect, ctx.metadata).rects;
|
|
2741
|
+
case "rotate":
|
|
2742
|
+
return baseRotateChanges(orig, ctx) ?? ctx.changes;
|
|
2743
|
+
case "property-update":
|
|
2744
|
+
if (ctx.changes.rotation !== void 0) {
|
|
2745
|
+
return { ...ctx.changes, ...basePropertyRotationChanges(orig, ctx.changes.rotation) };
|
|
2746
|
+
}
|
|
2747
|
+
return ctx.changes;
|
|
2748
|
+
default:
|
|
2749
|
+
return ctx.changes;
|
|
2750
|
+
}
|
|
2751
|
+
};
|
|
2752
|
+
const patchSquare = (orig, ctx) => {
|
|
2753
|
+
switch (ctx.type) {
|
|
2754
|
+
case "move":
|
|
2755
|
+
if (!ctx.changes.rect) return ctx.changes;
|
|
2756
|
+
return baseMoveChanges(orig, ctx.changes.rect).rects;
|
|
2757
|
+
case "resize":
|
|
2758
|
+
if (!ctx.changes.rect) return ctx.changes;
|
|
2759
|
+
return baseResizeScaling(orig, ctx.changes.rect, ctx.metadata).rects;
|
|
2760
|
+
case "rotate":
|
|
2761
|
+
return baseRotateChanges(orig, ctx) ?? ctx.changes;
|
|
2762
|
+
case "property-update":
|
|
2763
|
+
if (ctx.changes.rotation !== void 0) {
|
|
2764
|
+
return { ...ctx.changes, ...basePropertyRotationChanges(orig, ctx.changes.rotation) };
|
|
2454
2765
|
}
|
|
2455
2766
|
return ctx.changes;
|
|
2767
|
+
default:
|
|
2768
|
+
return ctx.changes;
|
|
2769
|
+
}
|
|
2770
|
+
};
|
|
2771
|
+
const patchFreeText = (orig, ctx) => {
|
|
2772
|
+
switch (ctx.type) {
|
|
2773
|
+
case "move":
|
|
2774
|
+
if (!ctx.changes.rect) return ctx.changes;
|
|
2775
|
+
return baseMoveChanges(orig, ctx.changes.rect).rects;
|
|
2776
|
+
case "resize":
|
|
2777
|
+
if (!ctx.changes.rect) return ctx.changes;
|
|
2778
|
+
return baseResizeScaling(orig, ctx.changes.rect, ctx.metadata).rects;
|
|
2779
|
+
case "rotate":
|
|
2780
|
+
return baseRotateChanges(orig, ctx) ?? ctx.changes;
|
|
2781
|
+
case "property-update":
|
|
2782
|
+
if (ctx.changes.rotation !== void 0) {
|
|
2783
|
+
return { ...ctx.changes, ...basePropertyRotationChanges(orig, ctx.changes.rotation) };
|
|
2784
|
+
}
|
|
2785
|
+
return ctx.changes;
|
|
2786
|
+
default:
|
|
2787
|
+
return ctx.changes;
|
|
2788
|
+
}
|
|
2789
|
+
};
|
|
2790
|
+
const patchStamp = (orig, ctx) => {
|
|
2791
|
+
switch (ctx.type) {
|
|
2792
|
+
case "move":
|
|
2793
|
+
if (!ctx.changes.rect) return ctx.changes;
|
|
2794
|
+
return baseMoveChanges(orig, ctx.changes.rect).rects;
|
|
2795
|
+
case "resize":
|
|
2796
|
+
if (!ctx.changes.rect) return ctx.changes;
|
|
2797
|
+
return baseResizeScaling(orig, ctx.changes.rect, ctx.metadata).rects;
|
|
2798
|
+
case "rotate":
|
|
2799
|
+
return baseRotateChanges(orig, ctx) ?? ctx.changes;
|
|
2456
2800
|
case "property-update":
|
|
2457
|
-
if (ctx.changes.
|
|
2458
|
-
|
|
2459
|
-
const pad = merged.strokeWidth / 2;
|
|
2460
|
-
const rect = expandRect(rectFromPoints(merged.vertices), pad);
|
|
2461
|
-
return { ...ctx.changes, rect };
|
|
2801
|
+
if (ctx.changes.rotation !== void 0) {
|
|
2802
|
+
return { ...ctx.changes, ...basePropertyRotationChanges(orig, ctx.changes.rotation) };
|
|
2462
2803
|
}
|
|
2463
2804
|
return ctx.changes;
|
|
2464
2805
|
default:
|
|
2465
2806
|
return ctx.changes;
|
|
2466
2807
|
}
|
|
2467
2808
|
};
|
|
2809
|
+
function convertAABBRectToUnrotatedSpace(newAABBRect, originalAABBRect, originalUnrotatedRect, rotationDegrees) {
|
|
2810
|
+
const theta = rotationDegrees * Math.PI / 180;
|
|
2811
|
+
const A = Math.abs(Math.cos(theta));
|
|
2812
|
+
const B = Math.abs(Math.sin(theta));
|
|
2813
|
+
const det = A * A - B * B;
|
|
2814
|
+
const newAABBw = newAABBRect.size.width;
|
|
2815
|
+
const newAABBh = newAABBRect.size.height;
|
|
2816
|
+
let newWidth;
|
|
2817
|
+
let newHeight;
|
|
2818
|
+
if (Math.abs(det) > 1e-6) {
|
|
2819
|
+
newWidth = (A * newAABBw - B * newAABBh) / det;
|
|
2820
|
+
newHeight = (A * newAABBh - B * newAABBw) / det;
|
|
2821
|
+
newWidth = Math.max(newWidth, 1);
|
|
2822
|
+
newHeight = Math.max(newHeight, 1);
|
|
2823
|
+
} else {
|
|
2824
|
+
const origArea = originalAABBRect.size.width * originalAABBRect.size.height;
|
|
2825
|
+
const newArea = newAABBw * newAABBh;
|
|
2826
|
+
const uniformScale = origArea > 0 ? Math.sqrt(newArea / origArea) : 1;
|
|
2827
|
+
newWidth = originalUnrotatedRect.size.width * uniformScale;
|
|
2828
|
+
newHeight = originalUnrotatedRect.size.height * uniformScale;
|
|
2829
|
+
}
|
|
2830
|
+
const newCenterX = newAABBRect.origin.x + newAABBw / 2;
|
|
2831
|
+
const newCenterY = newAABBRect.origin.y + newAABBh / 2;
|
|
2832
|
+
return {
|
|
2833
|
+
origin: { x: newCenterX - newWidth / 2, y: newCenterY - newHeight / 2 },
|
|
2834
|
+
size: { width: newWidth, height: newHeight }
|
|
2835
|
+
};
|
|
2836
|
+
}
|
|
2468
2837
|
const _AnnotationPlugin = class _AnnotationPlugin extends BasePlugin {
|
|
2469
2838
|
constructor(id, registry, config) {
|
|
2470
2839
|
var _a, _b, _c;
|
|
@@ -2484,6 +2853,8 @@ const _AnnotationPlugin = class _AnnotationPlugin extends BasePlugin {
|
|
|
2484
2853
|
this.unifiedDrag$ = createBehaviorEmitter();
|
|
2485
2854
|
this.unifiedResizeStates = /* @__PURE__ */ new Map();
|
|
2486
2855
|
this.unifiedResize$ = createBehaviorEmitter();
|
|
2856
|
+
this.unifiedRotateStates = /* @__PURE__ */ new Map();
|
|
2857
|
+
this.unifiedRotate$ = createBehaviorEmitter();
|
|
2487
2858
|
this.config = config;
|
|
2488
2859
|
this.selection = ((_a = registry.getPlugin("selection")) == null ? void 0 : _a.provides()) ?? null;
|
|
2489
2860
|
this.history = ((_b = registry.getPlugin("history")) == null ? void 0 : _b.provides()) ?? null;
|
|
@@ -2513,7 +2884,11 @@ const _AnnotationPlugin = class _AnnotationPlugin extends BasePlugin {
|
|
|
2513
2884
|
if (this.selection) {
|
|
2514
2885
|
for (const tool of this.state.tools) {
|
|
2515
2886
|
if (tool.interaction.textSelection) {
|
|
2516
|
-
this.selection.enableForMode(tool.interaction.mode ?? tool.id, {
|
|
2887
|
+
this.selection.enableForMode(tool.interaction.mode ?? tool.id, {
|
|
2888
|
+
showSelectionRects: false,
|
|
2889
|
+
enableSelection: true,
|
|
2890
|
+
enableMarquee: false
|
|
2891
|
+
});
|
|
2517
2892
|
}
|
|
2518
2893
|
}
|
|
2519
2894
|
}
|
|
@@ -2544,6 +2919,10 @@ const _AnnotationPlugin = class _AnnotationPlugin extends BasePlugin {
|
|
|
2544
2919
|
this.patchRegistry.register(PdfAnnotationSubtype.LINE, patchLine);
|
|
2545
2920
|
this.patchRegistry.register(PdfAnnotationSubtype.POLYLINE, patchPolyline);
|
|
2546
2921
|
this.patchRegistry.register(PdfAnnotationSubtype.POLYGON, patchPolygon);
|
|
2922
|
+
this.patchRegistry.register(PdfAnnotationSubtype.CIRCLE, patchCircle);
|
|
2923
|
+
this.patchRegistry.register(PdfAnnotationSubtype.SQUARE, patchSquare);
|
|
2924
|
+
this.patchRegistry.register(PdfAnnotationSubtype.FREETEXT, patchFreeText);
|
|
2925
|
+
this.patchRegistry.register(PdfAnnotationSubtype.STAMP, patchStamp);
|
|
2547
2926
|
}
|
|
2548
2927
|
async initialize() {
|
|
2549
2928
|
var _a, _b, _c;
|
|
@@ -2563,7 +2942,8 @@ const _AnnotationPlugin = class _AnnotationPlugin extends BasePlugin {
|
|
|
2563
2942
|
this.dispatch(setActiveToolId(s.documentId, newToolId));
|
|
2564
2943
|
}
|
|
2565
2944
|
});
|
|
2566
|
-
(_b = this.selection) == null ? void 0 : _b.onMarqueeEnd(({ documentId, pageIndex, rect }) => {
|
|
2945
|
+
(_b = this.selection) == null ? void 0 : _b.onMarqueeEnd(({ documentId, pageIndex, rect, modeId }) => {
|
|
2946
|
+
if (modeId !== "pointerMode") return;
|
|
2567
2947
|
const docState = this.state.documents[documentId];
|
|
2568
2948
|
if (!docState) return;
|
|
2569
2949
|
const pageAnnotations = (docState.pages[pageIndex] ?? []).map((uid) => docState.byUid[uid]).filter((ta) => ta !== void 0).filter((ta) => !isLink(ta));
|
|
@@ -2595,6 +2975,7 @@ const _AnnotationPlugin = class _AnnotationPlugin extends BasePlugin {
|
|
|
2595
2975
|
if (!formattedSelection || !selectionText) return;
|
|
2596
2976
|
for (const selection of formattedSelection) {
|
|
2597
2977
|
selectionText.wait((text) => {
|
|
2978
|
+
var _a3, _b3;
|
|
2598
2979
|
const annotationId = uuidV4();
|
|
2599
2980
|
this.createAnnotation(
|
|
2600
2981
|
selection.pageIndex,
|
|
@@ -2612,10 +2993,10 @@ const _AnnotationPlugin = class _AnnotationPlugin extends BasePlugin {
|
|
|
2612
2993
|
void 0,
|
|
2613
2994
|
documentId
|
|
2614
2995
|
);
|
|
2615
|
-
if (
|
|
2996
|
+
if ((_a3 = activeTool.behavior) == null ? void 0 : _a3.deactivateToolAfterCreate) {
|
|
2616
2997
|
this.setActiveTool(null, documentId);
|
|
2617
2998
|
}
|
|
2618
|
-
if (
|
|
2999
|
+
if ((_b3 = activeTool.behavior) == null ? void 0 : _b3.selectAfterCreate) {
|
|
2619
3000
|
this.selectAnnotation(selection.pageIndex, annotationId, documentId);
|
|
2620
3001
|
}
|
|
2621
3002
|
}, ignore);
|
|
@@ -2752,6 +3133,9 @@ const _AnnotationPlugin = class _AnnotationPlugin extends BasePlugin {
|
|
|
2752
3133
|
tool: this.getActiveTool(documentId)
|
|
2753
3134
|
});
|
|
2754
3135
|
}
|
|
3136
|
+
if ((prevDoc == null ? void 0 : prevDoc.selectedUids) !== nextDoc.selectedUids) {
|
|
3137
|
+
this.updateAnnotationSelectionActivity(documentId, nextDoc);
|
|
3138
|
+
}
|
|
2755
3139
|
}
|
|
2756
3140
|
}
|
|
2757
3141
|
if (prev.tools !== next.tools) {
|
|
@@ -2786,6 +3170,7 @@ const _AnnotationPlugin = class _AnnotationPlugin extends BasePlugin {
|
|
|
2786
3170
|
if (!this.interactionManager) return () => {
|
|
2787
3171
|
};
|
|
2788
3172
|
const unregisterFns = [];
|
|
3173
|
+
const effectivePageRotation = ((page.rotation ?? 0) + ((docState == null ? void 0 : docState.rotation) ?? 0)) % 4;
|
|
2789
3174
|
for (const tool of this.state.tools) {
|
|
2790
3175
|
if (!tool.defaults.type) continue;
|
|
2791
3176
|
const factory = this.handlerFactories.get(tool.defaults.type);
|
|
@@ -2793,16 +3178,18 @@ const _AnnotationPlugin = class _AnnotationPlugin extends BasePlugin {
|
|
|
2793
3178
|
const context = {
|
|
2794
3179
|
pageIndex,
|
|
2795
3180
|
pageSize: page.size,
|
|
3181
|
+
pageRotation: effectivePageRotation,
|
|
2796
3182
|
scale,
|
|
2797
3183
|
services: callbacks.services,
|
|
2798
3184
|
// Pass through services
|
|
2799
3185
|
onPreview: (state) => callbacks.onPreview(tool.id, state),
|
|
2800
3186
|
onCommit: (annotation, ctx) => {
|
|
3187
|
+
var _a2, _b;
|
|
2801
3188
|
this.createAnnotation(pageIndex, annotation, ctx, documentId);
|
|
2802
|
-
if (
|
|
3189
|
+
if ((_a2 = tool.behavior) == null ? void 0 : _a2.deactivateToolAfterCreate) {
|
|
2803
3190
|
this.setActiveTool(null, documentId);
|
|
2804
3191
|
}
|
|
2805
|
-
if (
|
|
3192
|
+
if ((_b = tool.behavior) == null ? void 0 : _b.selectAfterCreate) {
|
|
2806
3193
|
this.selectAnnotation(pageIndex, annotation.id, documentId);
|
|
2807
3194
|
}
|
|
2808
3195
|
},
|
|
@@ -3125,6 +3512,27 @@ const _AnnotationPlugin = class _AnnotationPlugin extends BasePlugin {
|
|
|
3125
3512
|
const docId = documentId ?? this.getActiveDocumentId();
|
|
3126
3513
|
this.dispatch(deselectAnnotation(docId));
|
|
3127
3514
|
}
|
|
3515
|
+
/**
|
|
3516
|
+
* Derive page activity from the current annotation selection.
|
|
3517
|
+
* Called from onStoreUpdated whenever selectedUids changes,
|
|
3518
|
+
* so ALL selection code paths are covered automatically.
|
|
3519
|
+
*/
|
|
3520
|
+
updateAnnotationSelectionActivity(docId, docState) {
|
|
3521
|
+
var _a, _b;
|
|
3522
|
+
if (docState.selectedUids.length === 0) {
|
|
3523
|
+
(_a = this.interactionManager) == null ? void 0 : _a.releasePageActivity(docId, "annotation-selection");
|
|
3524
|
+
return;
|
|
3525
|
+
}
|
|
3526
|
+
const firstUid = docState.selectedUids[0];
|
|
3527
|
+
const ta = docState.byUid[firstUid];
|
|
3528
|
+
if (ta) {
|
|
3529
|
+
(_b = this.interactionManager) == null ? void 0 : _b.claimPageActivity(
|
|
3530
|
+
docId,
|
|
3531
|
+
"annotation-selection",
|
|
3532
|
+
ta.object.pageIndex
|
|
3533
|
+
);
|
|
3534
|
+
}
|
|
3535
|
+
}
|
|
3128
3536
|
// ─────────────────────────────────────────────────────────
|
|
3129
3537
|
// Multi-Select Methods
|
|
3130
3538
|
// ─────────────────────────────────────────────────────────
|
|
@@ -3505,6 +3913,7 @@ const _AnnotationPlugin = class _AnnotationPlugin extends BasePlugin {
|
|
|
3505
3913
|
return annotations.map((anno) => ({
|
|
3506
3914
|
id: anno.id,
|
|
3507
3915
|
originalRect: anno.rect,
|
|
3916
|
+
originalUnrotatedRect: anno.unrotatedRect,
|
|
3508
3917
|
pageIndex: anno.pageIndex,
|
|
3509
3918
|
isAttachedLink: anno.isAttachedLink,
|
|
3510
3919
|
parentId: anno.parentId,
|
|
@@ -3541,12 +3950,24 @@ const _AnnotationPlugin = class _AnnotationPlugin extends BasePlugin {
|
|
|
3541
3950
|
*/
|
|
3542
3951
|
computeResizePreviewPatches(computedRects, documentId) {
|
|
3543
3952
|
const previewPatches = {};
|
|
3953
|
+
const state = this.unifiedResizeStates.get(documentId);
|
|
3954
|
+
const participantMap = state ? new Map(state.participatingAnnotations.map((p) => [p.id, p])) : void 0;
|
|
3544
3955
|
for (const [id, newRect] of computedRects) {
|
|
3545
3956
|
const ta = this.getAnnotationById(id, documentId);
|
|
3546
3957
|
if (!ta) continue;
|
|
3958
|
+
let targetRect = newRect;
|
|
3959
|
+
const info = participantMap == null ? void 0 : participantMap.get(id);
|
|
3960
|
+
if ((state == null ? void 0 : state.isGroupResize) && (info == null ? void 0 : info.originalUnrotatedRect)) {
|
|
3961
|
+
targetRect = convertAABBRectToUnrotatedSpace(
|
|
3962
|
+
newRect,
|
|
3963
|
+
info.originalRect,
|
|
3964
|
+
info.originalUnrotatedRect,
|
|
3965
|
+
ta.object.rotation ?? 0
|
|
3966
|
+
);
|
|
3967
|
+
}
|
|
3547
3968
|
previewPatches[id] = this.transformAnnotation(ta.object, {
|
|
3548
3969
|
type: "resize",
|
|
3549
|
-
changes: { rect:
|
|
3970
|
+
changes: { rect: targetRect }
|
|
3550
3971
|
});
|
|
3551
3972
|
}
|
|
3552
3973
|
return previewPatches;
|
|
@@ -3568,6 +3989,7 @@ const _AnnotationPlugin = class _AnnotationPlugin extends BasePlugin {
|
|
|
3568
3989
|
annotationsWithLinks.push({
|
|
3569
3990
|
id,
|
|
3570
3991
|
rect: ta.object.rect,
|
|
3992
|
+
unrotatedRect: ta.object.unrotatedRect ? this.cloneRect(ta.object.unrotatedRect) : void 0,
|
|
3571
3993
|
pageIndex: ta.object.pageIndex,
|
|
3572
3994
|
isAttachedLink: false
|
|
3573
3995
|
});
|
|
@@ -3578,6 +4000,7 @@ const _AnnotationPlugin = class _AnnotationPlugin extends BasePlugin {
|
|
|
3578
4000
|
annotationsWithLinks.push({
|
|
3579
4001
|
id: link.object.id,
|
|
3580
4002
|
rect: link.object.rect,
|
|
4003
|
+
unrotatedRect: link.object.unrotatedRect ? this.cloneRect(link.object.unrotatedRect) : void 0,
|
|
3581
4004
|
pageIndex: link.object.pageIndex,
|
|
3582
4005
|
isAttachedLink: true,
|
|
3583
4006
|
parentId: id
|
|
@@ -3597,6 +4020,7 @@ const _AnnotationPlugin = class _AnnotationPlugin extends BasePlugin {
|
|
|
3597
4020
|
const state = {
|
|
3598
4021
|
documentId,
|
|
3599
4022
|
isResizing: true,
|
|
4023
|
+
isGroupResize: annotationIds.length > 1,
|
|
3600
4024
|
primaryIds: annotationIds,
|
|
3601
4025
|
attachedLinkIds,
|
|
3602
4026
|
allParticipantIds,
|
|
@@ -3663,12 +4087,23 @@ const _AnnotationPlugin = class _AnnotationPlugin extends BasePlugin {
|
|
|
3663
4087
|
state.currentGroupBox
|
|
3664
4088
|
);
|
|
3665
4089
|
const patches = [];
|
|
4090
|
+
const participantMap = new Map(state.participatingAnnotations.map((p) => [p.id, p]));
|
|
3666
4091
|
for (const [id, newRect] of computedRects) {
|
|
3667
4092
|
const ta = this.getAnnotationById(id, documentId);
|
|
3668
4093
|
if (!ta) continue;
|
|
4094
|
+
let targetRect = newRect;
|
|
4095
|
+
const info = participantMap.get(id);
|
|
4096
|
+
if (state.isGroupResize && (info == null ? void 0 : info.originalUnrotatedRect)) {
|
|
4097
|
+
targetRect = convertAABBRectToUnrotatedSpace(
|
|
4098
|
+
newRect,
|
|
4099
|
+
info.originalRect,
|
|
4100
|
+
info.originalUnrotatedRect,
|
|
4101
|
+
ta.object.rotation ?? 0
|
|
4102
|
+
);
|
|
4103
|
+
}
|
|
3669
4104
|
const patch = this.transformAnnotation(ta.object, {
|
|
3670
4105
|
type: "resize",
|
|
3671
|
-
changes: { rect:
|
|
4106
|
+
changes: { rect: targetRect }
|
|
3672
4107
|
});
|
|
3673
4108
|
patches.push({ pageIndex: ta.object.pageIndex, id, patch });
|
|
3674
4109
|
}
|
|
@@ -3719,6 +4154,206 @@ const _AnnotationPlugin = class _AnnotationPlugin extends BasePlugin {
|
|
|
3719
4154
|
get onResizeChange() {
|
|
3720
4155
|
return this.unifiedResize$.on;
|
|
3721
4156
|
}
|
|
4157
|
+
// ─────────────────────────────────────────────────────────
|
|
4158
|
+
// Unified Rotation API (Plugin owns all rotation logic)
|
|
4159
|
+
// ─────────────────────────────────────────────────────────
|
|
4160
|
+
cloneRect(rect) {
|
|
4161
|
+
return {
|
|
4162
|
+
origin: { x: rect.origin.x, y: rect.origin.y },
|
|
4163
|
+
size: { width: rect.size.width, height: rect.size.height }
|
|
4164
|
+
};
|
|
4165
|
+
}
|
|
4166
|
+
translateRect(rect, delta) {
|
|
4167
|
+
return {
|
|
4168
|
+
origin: {
|
|
4169
|
+
x: rect.origin.x + delta.x,
|
|
4170
|
+
y: rect.origin.y + delta.y
|
|
4171
|
+
},
|
|
4172
|
+
size: { ...rect.size }
|
|
4173
|
+
};
|
|
4174
|
+
}
|
|
4175
|
+
normalizeAngle(angle) {
|
|
4176
|
+
const normalized = angle % 360;
|
|
4177
|
+
return normalized < 0 ? normalized + 360 : normalized;
|
|
4178
|
+
}
|
|
4179
|
+
normalizeDelta(delta) {
|
|
4180
|
+
const normalized = (delta + 540) % 360 - 180;
|
|
4181
|
+
return normalized;
|
|
4182
|
+
}
|
|
4183
|
+
buildRotationParticipants(annotationIds, documentId) {
|
|
4184
|
+
const participants = [];
|
|
4185
|
+
const attachedLinkIds = [];
|
|
4186
|
+
for (const id of annotationIds) {
|
|
4187
|
+
const ta = this.getAnnotationById(id, documentId);
|
|
4188
|
+
if (!ta) continue;
|
|
4189
|
+
participants.push({
|
|
4190
|
+
id,
|
|
4191
|
+
rect: this.cloneRect(ta.object.rect),
|
|
4192
|
+
pageIndex: ta.object.pageIndex,
|
|
4193
|
+
rotation: ta.object.rotation ?? 0,
|
|
4194
|
+
unrotatedRect: ta.object.unrotatedRect ? this.cloneRect(ta.object.unrotatedRect) : void 0,
|
|
4195
|
+
isAttachedLink: false
|
|
4196
|
+
});
|
|
4197
|
+
const links = this.getAttachedLinksMethod(id, documentId);
|
|
4198
|
+
for (const link of links) {
|
|
4199
|
+
if (attachedLinkIds.includes(link.object.id)) continue;
|
|
4200
|
+
attachedLinkIds.push(link.object.id);
|
|
4201
|
+
participants.push({
|
|
4202
|
+
id: link.object.id,
|
|
4203
|
+
rect: this.cloneRect(link.object.rect),
|
|
4204
|
+
pageIndex: link.object.pageIndex,
|
|
4205
|
+
rotation: link.object.rotation ?? 0,
|
|
4206
|
+
unrotatedRect: link.object.unrotatedRect ? this.cloneRect(link.object.unrotatedRect) : void 0,
|
|
4207
|
+
isAttachedLink: true,
|
|
4208
|
+
parentId: id
|
|
4209
|
+
});
|
|
4210
|
+
}
|
|
4211
|
+
}
|
|
4212
|
+
return { participants, attachedLinkIds };
|
|
4213
|
+
}
|
|
4214
|
+
computeRotatePreviewPatches(state, documentId) {
|
|
4215
|
+
const preview = {};
|
|
4216
|
+
for (const participant of state.participants) {
|
|
4217
|
+
const ta = this.getAnnotationById(participant.id, documentId);
|
|
4218
|
+
if (!ta) continue;
|
|
4219
|
+
const originalCenter = resolveAnnotationRotationCenter({
|
|
4220
|
+
rect: participant.rect,
|
|
4221
|
+
unrotatedRect: participant.unrotatedRect,
|
|
4222
|
+
rotation: participant.rotation
|
|
4223
|
+
});
|
|
4224
|
+
const rotatedCenter = rotatePointAround(
|
|
4225
|
+
originalCenter,
|
|
4226
|
+
state.rotationCenter,
|
|
4227
|
+
state.delta
|
|
4228
|
+
);
|
|
4229
|
+
const translation = {
|
|
4230
|
+
x: rotatedCenter.x - originalCenter.x,
|
|
4231
|
+
y: rotatedCenter.y - originalCenter.y
|
|
4232
|
+
};
|
|
4233
|
+
const nextRotation = this.normalizeAngle(participant.rotation + state.delta);
|
|
4234
|
+
const patch = this.transformAnnotation(ta.object, {
|
|
4235
|
+
type: "rotate",
|
|
4236
|
+
changes: {
|
|
4237
|
+
rotation: nextRotation,
|
|
4238
|
+
unrotatedRect: this.translateRect(
|
|
4239
|
+
participant.unrotatedRect ?? participant.rect,
|
|
4240
|
+
translation
|
|
4241
|
+
)
|
|
4242
|
+
},
|
|
4243
|
+
metadata: {
|
|
4244
|
+
rotationAngle: nextRotation,
|
|
4245
|
+
rotationDelta: state.delta,
|
|
4246
|
+
rotationCenter: state.rotationCenter
|
|
4247
|
+
}
|
|
4248
|
+
});
|
|
4249
|
+
if (!patch.rect && (translation.x !== 0 || translation.y !== 0)) {
|
|
4250
|
+
patch.rect = {
|
|
4251
|
+
origin: {
|
|
4252
|
+
x: ta.object.rect.origin.x + translation.x,
|
|
4253
|
+
y: ta.object.rect.origin.y + translation.y
|
|
4254
|
+
},
|
|
4255
|
+
size: { ...ta.object.rect.size }
|
|
4256
|
+
};
|
|
4257
|
+
}
|
|
4258
|
+
preview[participant.id] = patch;
|
|
4259
|
+
}
|
|
4260
|
+
return preview;
|
|
4261
|
+
}
|
|
4262
|
+
startRotation(documentId, options) {
|
|
4263
|
+
const { annotationIds, cursorAngle, rotationCenter } = options;
|
|
4264
|
+
const { participants, attachedLinkIds } = this.buildRotationParticipants(
|
|
4265
|
+
annotationIds,
|
|
4266
|
+
documentId
|
|
4267
|
+
);
|
|
4268
|
+
if (participants.length === 0) return;
|
|
4269
|
+
const rects = participants.map((p) => p.rect);
|
|
4270
|
+
const groupBox = this.computeUnifiedGroupBoundingBox(rects);
|
|
4271
|
+
const center = rotationCenter ?? {
|
|
4272
|
+
x: groupBox.origin.x + groupBox.size.width / 2,
|
|
4273
|
+
y: groupBox.origin.y + groupBox.size.height / 2
|
|
4274
|
+
};
|
|
4275
|
+
const state = {
|
|
4276
|
+
documentId,
|
|
4277
|
+
isRotating: true,
|
|
4278
|
+
primaryIds: annotationIds,
|
|
4279
|
+
attachedLinkIds,
|
|
4280
|
+
allParticipantIds: participants.map((p) => p.id),
|
|
4281
|
+
rotationCenter: center,
|
|
4282
|
+
cursorStartAngle: cursorAngle,
|
|
4283
|
+
currentAngle: cursorAngle,
|
|
4284
|
+
delta: 0,
|
|
4285
|
+
participants
|
|
4286
|
+
};
|
|
4287
|
+
this.unifiedRotateStates.set(documentId, state);
|
|
4288
|
+
const previewPatches = this.computeRotatePreviewPatches(state, documentId);
|
|
4289
|
+
this.unifiedRotate$.emit({
|
|
4290
|
+
documentId,
|
|
4291
|
+
type: "start",
|
|
4292
|
+
state,
|
|
4293
|
+
previewPatches
|
|
4294
|
+
});
|
|
4295
|
+
}
|
|
4296
|
+
updateRotation(documentId, cursorAngle, rotationDelta) {
|
|
4297
|
+
const state = this.unifiedRotateStates.get(documentId);
|
|
4298
|
+
if (!(state == null ? void 0 : state.isRotating)) {
|
|
4299
|
+
return;
|
|
4300
|
+
}
|
|
4301
|
+
const delta = rotationDelta !== void 0 ? rotationDelta : this.normalizeDelta(cursorAngle - state.cursorStartAngle);
|
|
4302
|
+
const newState = {
|
|
4303
|
+
...state,
|
|
4304
|
+
currentAngle: cursorAngle,
|
|
4305
|
+
delta
|
|
4306
|
+
};
|
|
4307
|
+
this.unifiedRotateStates.set(documentId, newState);
|
|
4308
|
+
const previewPatches = this.computeRotatePreviewPatches(newState, documentId);
|
|
4309
|
+
this.unifiedRotate$.emit({
|
|
4310
|
+
documentId,
|
|
4311
|
+
type: "update",
|
|
4312
|
+
state: newState,
|
|
4313
|
+
previewPatches
|
|
4314
|
+
});
|
|
4315
|
+
}
|
|
4316
|
+
commitRotation(documentId) {
|
|
4317
|
+
const state = this.unifiedRotateStates.get(documentId);
|
|
4318
|
+
if (!state) return;
|
|
4319
|
+
const previewPatches = this.computeRotatePreviewPatches(state, documentId);
|
|
4320
|
+
const patches = [];
|
|
4321
|
+
for (const [id, patch] of Object.entries(previewPatches)) {
|
|
4322
|
+
const ta = this.getAnnotationById(id, documentId);
|
|
4323
|
+
if (!ta) continue;
|
|
4324
|
+
patches.push({ pageIndex: ta.object.pageIndex, id, patch });
|
|
4325
|
+
}
|
|
4326
|
+
if (patches.length > 0) {
|
|
4327
|
+
this.updateAnnotationsMethod(patches, documentId);
|
|
4328
|
+
}
|
|
4329
|
+
this.unifiedRotate$.emit({
|
|
4330
|
+
documentId,
|
|
4331
|
+
type: "end",
|
|
4332
|
+
state: { ...state, isRotating: false },
|
|
4333
|
+
previewPatches
|
|
4334
|
+
});
|
|
4335
|
+
this.unifiedRotateStates.delete(documentId);
|
|
4336
|
+
}
|
|
4337
|
+
cancelRotation(documentId) {
|
|
4338
|
+
const state = this.unifiedRotateStates.get(documentId);
|
|
4339
|
+
if (!state) return;
|
|
4340
|
+
this.unifiedRotate$.emit({
|
|
4341
|
+
documentId,
|
|
4342
|
+
type: "cancel",
|
|
4343
|
+
state: { ...state, isRotating: false, delta: 0, currentAngle: state.cursorStartAngle },
|
|
4344
|
+
previewPatches: {}
|
|
4345
|
+
});
|
|
4346
|
+
this.unifiedRotateStates.delete(documentId);
|
|
4347
|
+
}
|
|
4348
|
+
getRotateState(documentId) {
|
|
4349
|
+
return this.unifiedRotateStates.get(documentId) ?? null;
|
|
4350
|
+
}
|
|
4351
|
+
/**
|
|
4352
|
+
* Subscribe to unified rotation state changes.
|
|
4353
|
+
*/
|
|
4354
|
+
get onRotateChange() {
|
|
4355
|
+
return this.unifiedRotate$.on;
|
|
4356
|
+
}
|
|
3722
4357
|
updateAnnotationsMethod(patches, documentId) {
|
|
3723
4358
|
const docId = documentId ?? this.getActiveDocumentId();
|
|
3724
4359
|
if (!this.checkPermission(docId, PdfPermissionFlag.ModifyAnnotations)) {
|
|
@@ -4011,17 +4646,6 @@ const _AnnotationPlugin = class _AnnotationPlugin extends BasePlugin {
|
|
|
4011
4646
|
);
|
|
4012
4647
|
return task;
|
|
4013
4648
|
}
|
|
4014
|
-
/**
|
|
4015
|
-
* Gets the effective behavior setting for a tool, checking tool-specific config first,
|
|
4016
|
-
* then falling back to plugin config.
|
|
4017
|
-
*/
|
|
4018
|
-
getToolBehavior(tool, setting) {
|
|
4019
|
-
var _a;
|
|
4020
|
-
if (((_a = tool.behavior) == null ? void 0 : _a[setting]) !== void 0) {
|
|
4021
|
-
return tool.behavior[setting];
|
|
4022
|
-
}
|
|
4023
|
-
return this.config[setting] !== false;
|
|
4024
|
-
}
|
|
4025
4649
|
};
|
|
4026
4650
|
_AnnotationPlugin.id = "annotation";
|
|
4027
4651
|
let AnnotationPlugin = _AnnotationPlugin;
|
|
@@ -4058,6 +4682,9 @@ export {
|
|
|
4058
4682
|
ANNOTATION_PLUGIN_ID,
|
|
4059
4683
|
AnnotationPlugin,
|
|
4060
4684
|
AnnotationPluginPackage,
|
|
4685
|
+
calculateRotatedRectAABB2 as calculateRotatedRectAABB,
|
|
4686
|
+
calculateRotatedRectAABBAroundPoint2 as calculateRotatedRectAABBAroundPoint,
|
|
4687
|
+
convertAABBRectToUnrotatedSpace,
|
|
4061
4688
|
createToolPredicate,
|
|
4062
4689
|
getAnnotationByUid,
|
|
4063
4690
|
getAnnotations,
|
|
@@ -4067,6 +4694,7 @@ export {
|
|
|
4067
4694
|
getGroupMembers,
|
|
4068
4695
|
getIRTChildIds,
|
|
4069
4696
|
getIRTChildrenByType,
|
|
4697
|
+
getRectCenter2 as getRectCenter,
|
|
4070
4698
|
getSelectedAnnotation,
|
|
4071
4699
|
getSelectedAnnotationByPageIndex,
|
|
4072
4700
|
getSelectedAnnotationIds,
|
|
@@ -4079,6 +4707,7 @@ export {
|
|
|
4079
4707
|
hasAttachedLinks,
|
|
4080
4708
|
hasIRTChildren,
|
|
4081
4709
|
hasMultipleSelected,
|
|
4710
|
+
inferRotationCenterFromRects2 as inferRotationCenterFromRects,
|
|
4082
4711
|
initialDocumentState,
|
|
4083
4712
|
initialState,
|
|
4084
4713
|
isAnnotationSelected,
|
|
@@ -4116,6 +4745,8 @@ export {
|
|
|
4116
4745
|
manifest,
|
|
4117
4746
|
index as patching,
|
|
4118
4747
|
rectsIntersect,
|
|
4119
|
-
resolveInteractionProp
|
|
4748
|
+
resolveInteractionProp,
|
|
4749
|
+
rotatePointAround2 as rotatePointAroundCenter,
|
|
4750
|
+
rotateVertices2 as rotateVertices
|
|
4120
4751
|
};
|
|
4121
4752
|
//# sourceMappingURL=index.js.map
|