@embedpdf/plugin-annotation 2.12.1 → 2.13.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.
- package/dist/index.cjs +1 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +1437 -1429
- package/dist/index.js.map +1 -1
- package/dist/lib/patching/index.d.ts +1 -0
- package/package.json +12 -12
package/dist/index.js
CHANGED
|
@@ -893,495 +893,252 @@ function clampAnnotationToPage(annotation, pageSize) {
|
|
|
893
893
|
} : {}
|
|
894
894
|
};
|
|
895
895
|
}
|
|
896
|
-
const
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
const
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
896
|
+
const patchInk = (original, ctx) => {
|
|
897
|
+
switch (ctx.type) {
|
|
898
|
+
case "vertex-edit":
|
|
899
|
+
return ctx.changes;
|
|
900
|
+
case "move": {
|
|
901
|
+
if (!ctx.changes.rect) return ctx.changes;
|
|
902
|
+
const { dx, dy, rects } = baseMoveChanges(original, ctx.changes.rect);
|
|
903
|
+
return {
|
|
904
|
+
...rects,
|
|
905
|
+
inkList: original.inkList.map((stroke) => ({
|
|
906
|
+
points: stroke.points.map((p) => ({ x: p.x + dx, y: p.y + dy }))
|
|
907
|
+
}))
|
|
908
|
+
};
|
|
909
|
+
}
|
|
910
|
+
case "resize": {
|
|
911
|
+
if (!ctx.changes.rect) return ctx.changes;
|
|
912
|
+
const { scaleX, scaleY, oldRect, resolvedRect, rects } = baseResizeScaling(
|
|
913
|
+
original,
|
|
914
|
+
ctx.changes.rect,
|
|
915
|
+
ctx.metadata
|
|
916
|
+
);
|
|
917
|
+
const inset = (r2, pad) => ({
|
|
918
|
+
origin: { x: r2.origin.x + pad, y: r2.origin.y + pad },
|
|
919
|
+
size: {
|
|
920
|
+
width: Math.max(1, r2.size.width - pad * 2),
|
|
921
|
+
height: Math.max(1, r2.size.height - pad * 2)
|
|
922
|
+
}
|
|
923
|
+
});
|
|
924
|
+
const resizeEpsilon = 1e-3;
|
|
925
|
+
const widthChanged = Math.abs(scaleX - 1) > resizeEpsilon;
|
|
926
|
+
const heightChanged = Math.abs(scaleY - 1) > resizeEpsilon;
|
|
927
|
+
const strokeScale = widthChanged && !heightChanged ? scaleX : !widthChanged && heightChanged ? scaleY : Math.min(scaleX, scaleY);
|
|
928
|
+
const rawStrokeWidth = Math.max(1, original.strokeWidth * strokeScale);
|
|
929
|
+
const maxStrokeWidth = Math.max(
|
|
930
|
+
1,
|
|
931
|
+
Math.min(resolvedRect.size.width, resolvedRect.size.height)
|
|
932
|
+
);
|
|
933
|
+
const clampedStrokeWidth = Math.min(rawStrokeWidth, maxStrokeWidth);
|
|
934
|
+
const newStrokeWidth = Number(clampedStrokeWidth.toFixed(1));
|
|
935
|
+
const innerOld = inset(oldRect, original.strokeWidth / 2);
|
|
936
|
+
const innerNew = inset(resolvedRect, newStrokeWidth / 2);
|
|
937
|
+
const sx = innerNew.size.width / Math.max(innerOld.size.width, 1e-6);
|
|
938
|
+
const sy = innerNew.size.height / Math.max(innerOld.size.height, 1e-6);
|
|
939
|
+
return {
|
|
940
|
+
...rects,
|
|
941
|
+
inkList: original.inkList.map((stroke) => ({
|
|
942
|
+
points: stroke.points.map((p) => ({
|
|
943
|
+
x: innerNew.origin.x + (p.x - innerOld.origin.x) * sx,
|
|
944
|
+
y: innerNew.origin.y + (p.y - innerOld.origin.y) * sy
|
|
945
|
+
}))
|
|
946
|
+
})),
|
|
947
|
+
strokeWidth: newStrokeWidth
|
|
948
|
+
};
|
|
949
|
+
}
|
|
950
|
+
case "rotate": {
|
|
951
|
+
const result = baseRotateChanges(original, ctx);
|
|
952
|
+
if (!result) return ctx.changes;
|
|
953
|
+
const { dx, dy } = rotateOrbitDelta(original, result);
|
|
954
|
+
return {
|
|
955
|
+
...result,
|
|
956
|
+
inkList: original.inkList.map((stroke) => ({
|
|
957
|
+
points: stroke.points.map((p) => ({ x: p.x + dx, y: p.y + dy }))
|
|
958
|
+
}))
|
|
959
|
+
};
|
|
960
|
+
}
|
|
961
|
+
case "property-update": {
|
|
962
|
+
const needsRectUpdate = ctx.changes.strokeWidth !== void 0 || ctx.changes.rotation !== void 0;
|
|
963
|
+
if (!needsRectUpdate) return ctx.changes;
|
|
964
|
+
const merged = { ...original, ...ctx.changes };
|
|
965
|
+
const pts = merged.inkList.flatMap((s) => s.points);
|
|
966
|
+
const tightRect = expandRect(rectFromPoints(pts), merged.strokeWidth / 2);
|
|
967
|
+
const effectiveRotation = ctx.changes.rotation ?? original.rotation ?? 0;
|
|
968
|
+
if (original.unrotatedRect || ctx.changes.rotation !== void 0) {
|
|
969
|
+
return {
|
|
970
|
+
...ctx.changes,
|
|
971
|
+
unrotatedRect: tightRect,
|
|
972
|
+
rect: calculateRotatedRectAABBAroundPoint(
|
|
973
|
+
tightRect,
|
|
974
|
+
effectiveRotation,
|
|
975
|
+
resolveAnnotationRotationCenter(original)
|
|
976
|
+
)
|
|
939
977
|
};
|
|
940
|
-
anno = clampAnnotationToPage(anno, pageSize);
|
|
941
|
-
onCommit(anno);
|
|
942
978
|
}
|
|
943
|
-
|
|
979
|
+
return { ...ctx.changes, rect: tightRect };
|
|
980
|
+
}
|
|
981
|
+
default:
|
|
982
|
+
return ctx.changes;
|
|
944
983
|
}
|
|
945
984
|
};
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
}
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
const start = getStartPos();
|
|
960
|
-
if (!start || getHasMoved()) return;
|
|
961
|
-
const distance2 = Math.sqrt(Math.pow(pos.x - start.x, 2) + Math.pow(pos.y - start.y, 2));
|
|
962
|
-
if (distance2 > threshold) {
|
|
963
|
-
setHasMoved(true);
|
|
985
|
+
const patchLine = (orig, ctx) => {
|
|
986
|
+
switch (ctx.type) {
|
|
987
|
+
case "vertex-edit":
|
|
988
|
+
if (ctx.changes.linePoints) {
|
|
989
|
+
const { start, end } = ctx.changes.linePoints;
|
|
990
|
+
const rawPoints = [start, end];
|
|
991
|
+
const rawRect = lineRectWithEndings(rawPoints, orig.strokeWidth, orig.lineEndings);
|
|
992
|
+
const compensated = compensateRotatedVertexEdit(orig, rawPoints, rawRect);
|
|
993
|
+
const rect = lineRectWithEndings(compensated, orig.strokeWidth, orig.lineEndings);
|
|
994
|
+
return {
|
|
995
|
+
...resolveVertexEditRects(orig, rect),
|
|
996
|
+
linePoints: { start: compensated[0], end: compensated[1] }
|
|
997
|
+
};
|
|
964
998
|
}
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
const
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
999
|
+
return ctx.changes;
|
|
1000
|
+
case "move": {
|
|
1001
|
+
if (!ctx.changes.rect) return ctx.changes;
|
|
1002
|
+
const { dx, dy, rects } = baseMoveChanges(orig, ctx.changes.rect);
|
|
1003
|
+
return {
|
|
1004
|
+
...rects,
|
|
1005
|
+
linePoints: {
|
|
1006
|
+
start: { x: orig.linePoints.start.x + dx, y: orig.linePoints.start.y + dy },
|
|
1007
|
+
end: { x: orig.linePoints.end.x + dx, y: orig.linePoints.end.y + dy }
|
|
973
1008
|
}
|
|
974
|
-
}
|
|
975
|
-
setStartPos(null);
|
|
976
|
-
setHasMoved(false);
|
|
977
|
-
},
|
|
978
|
-
hasMoved: getHasMoved,
|
|
979
|
-
reset: () => {
|
|
980
|
-
setStartPos(null);
|
|
981
|
-
setHasMoved(false);
|
|
1009
|
+
};
|
|
982
1010
|
}
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
const
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
const clampToPage = (pos) => ({
|
|
991
|
-
x: clamp(pos.x, 0, pageSize.width),
|
|
992
|
-
y: clamp(pos.y, 0, pageSize.height)
|
|
993
|
-
});
|
|
994
|
-
const getDefaults = () => {
|
|
995
|
-
const tool = getTool();
|
|
996
|
-
if (!tool) return null;
|
|
1011
|
+
case "resize": {
|
|
1012
|
+
if (!ctx.changes.rect) return ctx.changes;
|
|
1013
|
+
const { scaleX, scaleY, oldRect, resolvedRect, rects } = baseResizeScaling(
|
|
1014
|
+
orig,
|
|
1015
|
+
ctx.changes.rect,
|
|
1016
|
+
ctx.metadata
|
|
1017
|
+
);
|
|
997
1018
|
return {
|
|
998
|
-
...
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
};
|
|
1010
|
-
const clickDetector = useClickDetector({
|
|
1011
|
-
threshold: 5,
|
|
1012
|
-
getTool,
|
|
1013
|
-
onClickDetected: (pos, tool) => {
|
|
1014
|
-
var _a;
|
|
1015
|
-
const defaults = getDefaults();
|
|
1016
|
-
if (!defaults) return;
|
|
1017
|
-
const clickConfig = tool.clickBehavior;
|
|
1018
|
-
if (!(clickConfig == null ? void 0 : clickConfig.enabled)) return;
|
|
1019
|
-
const { width, height } = clickConfig.defaultSize;
|
|
1020
|
-
const rect = {
|
|
1021
|
-
origin: { x: pos.x - width / 2, y: pos.y - height / 2 },
|
|
1022
|
-
size: { width, height }
|
|
1023
|
-
};
|
|
1024
|
-
const contents = clickConfig.defaultContent ?? defaults.contents;
|
|
1025
|
-
let anno = {
|
|
1026
|
-
...defaults,
|
|
1027
|
-
contents,
|
|
1028
|
-
type: PdfAnnotationSubtype.FREETEXT,
|
|
1029
|
-
rect,
|
|
1030
|
-
pageIndex,
|
|
1031
|
-
id: uuidV4(),
|
|
1032
|
-
created: /* @__PURE__ */ new Date()
|
|
1033
|
-
};
|
|
1034
|
-
if ((_a = tool.behavior) == null ? void 0 : _a.insertUpright) {
|
|
1035
|
-
anno = applyInsertUpright(anno, pageRotation, false);
|
|
1036
|
-
}
|
|
1037
|
-
anno = clampAnnotationToPage(anno, pageSize);
|
|
1038
|
-
onCommit(anno);
|
|
1039
|
-
}
|
|
1040
|
-
});
|
|
1041
|
-
const getPreview = (current) => {
|
|
1042
|
-
const start = getStart();
|
|
1043
|
-
if (!start) return null;
|
|
1044
|
-
const defaults = getDefaults();
|
|
1045
|
-
if (!defaults) return null;
|
|
1046
|
-
const minX = Math.min(start.x, current.x);
|
|
1047
|
-
const minY = Math.min(start.y, current.y);
|
|
1048
|
-
const width = Math.abs(start.x - current.x);
|
|
1049
|
-
const height = Math.abs(start.y - current.y);
|
|
1050
|
-
const rect = {
|
|
1051
|
-
origin: { x: minX, y: minY },
|
|
1052
|
-
size: { width, height }
|
|
1019
|
+
...rects,
|
|
1020
|
+
linePoints: {
|
|
1021
|
+
start: {
|
|
1022
|
+
x: resolvedRect.origin.x + (orig.linePoints.start.x - oldRect.origin.x) * scaleX,
|
|
1023
|
+
y: resolvedRect.origin.y + (orig.linePoints.start.y - oldRect.origin.y) * scaleY
|
|
1024
|
+
},
|
|
1025
|
+
end: {
|
|
1026
|
+
x: resolvedRect.origin.x + (orig.linePoints.end.x - oldRect.origin.x) * scaleX,
|
|
1027
|
+
y: resolvedRect.origin.y + (orig.linePoints.end.y - oldRect.origin.y) * scaleY
|
|
1028
|
+
}
|
|
1029
|
+
}
|
|
1053
1030
|
};
|
|
1031
|
+
}
|
|
1032
|
+
case "rotate": {
|
|
1033
|
+
const result = baseRotateChanges(orig, ctx);
|
|
1034
|
+
if (!result) return ctx.changes;
|
|
1035
|
+
const { dx, dy } = rotateOrbitDelta(orig, result);
|
|
1054
1036
|
return {
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
rect
|
|
1037
|
+
...result,
|
|
1038
|
+
linePoints: {
|
|
1039
|
+
start: { x: orig.linePoints.start.x + dx, y: orig.linePoints.start.y + dy },
|
|
1040
|
+
end: { x: orig.linePoints.end.x + dx, y: orig.linePoints.end.y + dy }
|
|
1060
1041
|
}
|
|
1061
1042
|
};
|
|
1062
|
-
}
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
const defaults = getDefaults();
|
|
1084
|
-
if (!defaults) return;
|
|
1085
|
-
const clampedPos = clampToPage(pos);
|
|
1086
|
-
if (!clickDetector.hasMoved()) {
|
|
1087
|
-
clickDetector.onEnd(clampedPos);
|
|
1088
|
-
} else {
|
|
1089
|
-
const minX = Math.min(start.x, clampedPos.x);
|
|
1090
|
-
const minY = Math.min(start.y, clampedPos.y);
|
|
1091
|
-
const width = Math.abs(start.x - clampedPos.x);
|
|
1092
|
-
const height = Math.abs(start.y - clampedPos.y);
|
|
1093
|
-
const rect = {
|
|
1094
|
-
origin: { x: minX, y: minY },
|
|
1095
|
-
size: { width, height }
|
|
1096
|
-
};
|
|
1097
|
-
const tool = getTool();
|
|
1098
|
-
let anno = {
|
|
1099
|
-
...defaults,
|
|
1100
|
-
type: PdfAnnotationSubtype.FREETEXT,
|
|
1101
|
-
rect,
|
|
1102
|
-
pageIndex: context.pageIndex,
|
|
1103
|
-
id: uuidV4(),
|
|
1104
|
-
created: /* @__PURE__ */ new Date()
|
|
1105
|
-
};
|
|
1106
|
-
if ((_a = tool == null ? void 0 : tool.behavior) == null ? void 0 : _a.insertUpright) {
|
|
1107
|
-
anno = applyInsertUpright(anno, pageRotation, true);
|
|
1108
|
-
}
|
|
1109
|
-
onCommit(anno);
|
|
1110
|
-
}
|
|
1111
|
-
setStart(null);
|
|
1112
|
-
onPreview(null);
|
|
1113
|
-
clickDetector.reset();
|
|
1114
|
-
(_b = evt.releasePointerCapture) == null ? void 0 : _b.call(evt);
|
|
1115
|
-
},
|
|
1116
|
-
onPointerLeave: (_, evt) => {
|
|
1117
|
-
var _a;
|
|
1118
|
-
setStart(null);
|
|
1119
|
-
onPreview(null);
|
|
1120
|
-
clickDetector.reset();
|
|
1121
|
-
(_a = evt.releasePointerCapture) == null ? void 0 : _a.call(evt);
|
|
1122
|
-
},
|
|
1123
|
-
onPointerCancel: (_, evt) => {
|
|
1124
|
-
var _a;
|
|
1125
|
-
setStart(null);
|
|
1126
|
-
onPreview(null);
|
|
1127
|
-
clickDetector.reset();
|
|
1128
|
-
(_a = evt.releasePointerCapture) == null ? void 0 : _a.call(evt);
|
|
1043
|
+
}
|
|
1044
|
+
case "property-update": {
|
|
1045
|
+
const needsRectUpdate = ctx.changes.strokeWidth !== void 0 || ctx.changes.lineEndings !== void 0 || ctx.changes.rotation !== void 0;
|
|
1046
|
+
if (!needsRectUpdate) return ctx.changes;
|
|
1047
|
+
const merged = { ...orig, ...ctx.changes };
|
|
1048
|
+
const tightRect = lineRectWithEndings(
|
|
1049
|
+
[merged.linePoints.start, merged.linePoints.end],
|
|
1050
|
+
merged.strokeWidth,
|
|
1051
|
+
merged.lineEndings
|
|
1052
|
+
);
|
|
1053
|
+
const effectiveRotation = ctx.changes.rotation ?? orig.rotation ?? 0;
|
|
1054
|
+
if (orig.unrotatedRect || ctx.changes.rotation !== void 0) {
|
|
1055
|
+
return {
|
|
1056
|
+
...ctx.changes,
|
|
1057
|
+
unrotatedRect: tightRect,
|
|
1058
|
+
rect: calculateRotatedRectAABBAroundPoint(
|
|
1059
|
+
tightRect,
|
|
1060
|
+
effectiveRotation,
|
|
1061
|
+
resolveAnnotationRotationCenter(orig)
|
|
1062
|
+
)
|
|
1063
|
+
};
|
|
1129
1064
|
}
|
|
1130
|
-
|
|
1065
|
+
return { ...ctx.changes, rect: tightRect };
|
|
1066
|
+
}
|
|
1067
|
+
default:
|
|
1068
|
+
return ctx.changes;
|
|
1131
1069
|
}
|
|
1132
1070
|
};
|
|
1133
|
-
const
|
|
1134
|
-
|
|
1135
|
-
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
|
|
1140
|
-
|
|
1141
|
-
|
|
1142
|
-
|
|
1143
|
-
|
|
1144
|
-
|
|
1071
|
+
const patchPolyline = (orig, ctx) => {
|
|
1072
|
+
switch (ctx.type) {
|
|
1073
|
+
case "vertex-edit":
|
|
1074
|
+
if (ctx.changes.vertices && ctx.changes.vertices.length) {
|
|
1075
|
+
const rawVertices = ctx.changes.vertices;
|
|
1076
|
+
const rawRect = lineRectWithEndings(rawVertices, orig.strokeWidth, orig.lineEndings);
|
|
1077
|
+
const compensated = compensateRotatedVertexEdit(orig, rawVertices, rawRect);
|
|
1078
|
+
const rect = lineRectWithEndings(compensated, orig.strokeWidth, orig.lineEndings);
|
|
1079
|
+
return {
|
|
1080
|
+
...resolveVertexEditRects(orig, rect),
|
|
1081
|
+
vertices: compensated
|
|
1082
|
+
};
|
|
1083
|
+
}
|
|
1084
|
+
return ctx.changes;
|
|
1085
|
+
case "move": {
|
|
1086
|
+
if (!ctx.changes.rect) return ctx.changes;
|
|
1087
|
+
const { dx, dy, rects } = baseMoveChanges(orig, ctx.changes.rect);
|
|
1145
1088
|
return {
|
|
1146
|
-
...
|
|
1147
|
-
|
|
1148
|
-
lineEndings: tool.defaults.lineEndings ?? {
|
|
1149
|
-
start: PdfAnnotationLineEnding.None,
|
|
1150
|
-
end: PdfAnnotationLineEnding.None
|
|
1151
|
-
},
|
|
1152
|
-
color: tool.defaults.color ?? "#000000",
|
|
1153
|
-
opacity: tool.defaults.opacity ?? 1,
|
|
1154
|
-
strokeStyle: tool.defaults.strokeStyle ?? PdfAnnotationBorderStyle.SOLID,
|
|
1155
|
-
strokeDashArray: tool.defaults.strokeDashArray ?? [],
|
|
1156
|
-
strokeColor: tool.defaults.strokeColor ?? "#000000",
|
|
1157
|
-
flags: tool.defaults.flags ?? ["print"]
|
|
1089
|
+
...rects,
|
|
1090
|
+
vertices: orig.vertices.map((p) => ({ x: p.x + dx, y: p.y + dy }))
|
|
1158
1091
|
};
|
|
1159
|
-
}
|
|
1160
|
-
|
|
1161
|
-
|
|
1162
|
-
|
|
1163
|
-
|
|
1164
|
-
|
|
1165
|
-
|
|
1166
|
-
const clickConfig = tool.clickBehavior;
|
|
1167
|
-
if (!(clickConfig == null ? void 0 : clickConfig.enabled)) return;
|
|
1168
|
-
const angle = clickConfig.defaultAngle ?? 0;
|
|
1169
|
-
const length = clickConfig.defaultLength;
|
|
1170
|
-
const halfLength = length / 2;
|
|
1171
|
-
const startX = pos.x - halfLength * Math.cos(angle);
|
|
1172
|
-
const startY = pos.y - halfLength * Math.sin(angle);
|
|
1173
|
-
const endX = pos.x + halfLength * Math.cos(angle);
|
|
1174
|
-
const endY = pos.y + halfLength * Math.sin(angle);
|
|
1175
|
-
const start = clampToPage({ x: startX, y: startY });
|
|
1176
|
-
const end = clampToPage({ x: endX, y: endY });
|
|
1177
|
-
const rect = lineRectWithEndings(
|
|
1178
|
-
[start, end],
|
|
1179
|
-
defaults.strokeWidth,
|
|
1180
|
-
defaults.lineEndings
|
|
1181
|
-
);
|
|
1182
|
-
onCommit({
|
|
1183
|
-
...defaults,
|
|
1184
|
-
rect,
|
|
1185
|
-
linePoints: { start, end },
|
|
1186
|
-
pageIndex,
|
|
1187
|
-
id: uuidV4(),
|
|
1188
|
-
created: /* @__PURE__ */ new Date(),
|
|
1189
|
-
type: PdfAnnotationSubtype.LINE
|
|
1190
|
-
});
|
|
1191
|
-
}
|
|
1192
|
-
});
|
|
1193
|
-
const getPreview = (current) => {
|
|
1194
|
-
const start = getStart();
|
|
1195
|
-
if (!start) return null;
|
|
1196
|
-
const defaults = getDefaults();
|
|
1197
|
-
if (!defaults) return null;
|
|
1198
|
-
const bounds = lineRectWithEndings(
|
|
1199
|
-
[start, current],
|
|
1200
|
-
defaults.strokeWidth,
|
|
1201
|
-
defaults.lineEndings
|
|
1092
|
+
}
|
|
1093
|
+
case "resize": {
|
|
1094
|
+
if (!ctx.changes.rect) return ctx.changes;
|
|
1095
|
+
const { scaleX, scaleY, oldRect, resolvedRect, rects } = baseResizeScaling(
|
|
1096
|
+
orig,
|
|
1097
|
+
ctx.changes.rect,
|
|
1098
|
+
ctx.metadata
|
|
1202
1099
|
);
|
|
1203
1100
|
return {
|
|
1204
|
-
|
|
1205
|
-
|
|
1206
|
-
|
|
1207
|
-
|
|
1208
|
-
|
|
1209
|
-
linePoints: { start, end: current }
|
|
1210
|
-
}
|
|
1101
|
+
...rects,
|
|
1102
|
+
vertices: orig.vertices.map((v) => ({
|
|
1103
|
+
x: resolvedRect.origin.x + (v.x - oldRect.origin.x) * scaleX,
|
|
1104
|
+
y: resolvedRect.origin.y + (v.y - oldRect.origin.y) * scaleY
|
|
1105
|
+
}))
|
|
1211
1106
|
};
|
|
1212
|
-
}
|
|
1213
|
-
|
|
1214
|
-
|
|
1215
|
-
|
|
1216
|
-
|
|
1217
|
-
setStart(clampedPos);
|
|
1218
|
-
clickDetector.onStart(clampedPos);
|
|
1219
|
-
onPreview(getPreview(clampedPos));
|
|
1220
|
-
(_a = evt.setPointerCapture) == null ? void 0 : _a.call(evt);
|
|
1221
|
-
},
|
|
1222
|
-
onPointerMove: (pos) => {
|
|
1223
|
-
const clampedPos = clampToPage(pos);
|
|
1224
|
-
clickDetector.onMove(clampedPos);
|
|
1225
|
-
if (getStart() && clickDetector.hasMoved()) {
|
|
1226
|
-
onPreview(getPreview(clampedPos));
|
|
1227
|
-
}
|
|
1228
|
-
},
|
|
1229
|
-
onPointerUp: (pos, evt) => {
|
|
1230
|
-
var _a;
|
|
1231
|
-
const start = getStart();
|
|
1232
|
-
if (!start) return;
|
|
1233
|
-
const clampedPos = clampToPage(pos);
|
|
1234
|
-
if (!clickDetector.hasMoved()) {
|
|
1235
|
-
clickDetector.onEnd(clampedPos);
|
|
1236
|
-
} else {
|
|
1237
|
-
const defaults = getDefaults();
|
|
1238
|
-
if (!defaults) return;
|
|
1239
|
-
if (Math.abs(clampedPos.x - start.x) > 2 || Math.abs(clampedPos.y - start.y) > 2) {
|
|
1240
|
-
const rect = lineRectWithEndings(
|
|
1241
|
-
[start, clampedPos],
|
|
1242
|
-
defaults.strokeWidth,
|
|
1243
|
-
defaults.lineEndings
|
|
1244
|
-
);
|
|
1245
|
-
onCommit({
|
|
1246
|
-
...defaults,
|
|
1247
|
-
rect,
|
|
1248
|
-
linePoints: { start, end: clampedPos },
|
|
1249
|
-
pageIndex,
|
|
1250
|
-
id: uuidV4(),
|
|
1251
|
-
flags: ["print"],
|
|
1252
|
-
created: /* @__PURE__ */ new Date(),
|
|
1253
|
-
type: PdfAnnotationSubtype.LINE
|
|
1254
|
-
});
|
|
1255
|
-
}
|
|
1256
|
-
}
|
|
1257
|
-
setStart(null);
|
|
1258
|
-
onPreview(null);
|
|
1259
|
-
clickDetector.reset();
|
|
1260
|
-
(_a = evt.releasePointerCapture) == null ? void 0 : _a.call(evt);
|
|
1261
|
-
},
|
|
1262
|
-
onPointerLeave: (_, evt) => {
|
|
1263
|
-
var _a;
|
|
1264
|
-
setStart(null);
|
|
1265
|
-
onPreview(null);
|
|
1266
|
-
clickDetector.reset();
|
|
1267
|
-
(_a = evt.releasePointerCapture) == null ? void 0 : _a.call(evt);
|
|
1268
|
-
},
|
|
1269
|
-
onPointerCancel: (_, evt) => {
|
|
1270
|
-
var _a;
|
|
1271
|
-
setStart(null);
|
|
1272
|
-
onPreview(null);
|
|
1273
|
-
clickDetector.reset();
|
|
1274
|
-
(_a = evt.releasePointerCapture) == null ? void 0 : _a.call(evt);
|
|
1275
|
-
}
|
|
1276
|
-
};
|
|
1277
|
-
}
|
|
1278
|
-
};
|
|
1279
|
-
const polylineHandlerFactory = {
|
|
1280
|
-
annotationType: PdfAnnotationSubtype.POLYLINE,
|
|
1281
|
-
create(context) {
|
|
1282
|
-
const { onCommit, onPreview, getTool, pageSize } = context;
|
|
1283
|
-
const [getVertices, setVertices] = useState([]);
|
|
1284
|
-
const [getCurrent, setCurrent] = useState(null);
|
|
1285
|
-
const clampToPage = (pos) => ({
|
|
1286
|
-
x: clamp(pos.x, 0, pageSize.width),
|
|
1287
|
-
y: clamp(pos.y, 0, pageSize.height)
|
|
1288
|
-
});
|
|
1289
|
-
const getDefaults = () => {
|
|
1290
|
-
const tool = getTool();
|
|
1291
|
-
if (!tool) return null;
|
|
1107
|
+
}
|
|
1108
|
+
case "rotate": {
|
|
1109
|
+
const result = baseRotateChanges(orig, ctx);
|
|
1110
|
+
if (!result) return ctx.changes;
|
|
1111
|
+
const { dx, dy } = rotateOrbitDelta(orig, result);
|
|
1292
1112
|
return {
|
|
1293
|
-
...
|
|
1294
|
-
|
|
1295
|
-
lineEndings: tool.defaults.lineEndings ?? {
|
|
1296
|
-
start: PdfAnnotationLineEnding.None,
|
|
1297
|
-
end: PdfAnnotationLineEnding.None
|
|
1298
|
-
},
|
|
1299
|
-
color: tool.defaults.color ?? "#000000",
|
|
1300
|
-
opacity: tool.defaults.opacity ?? 1,
|
|
1301
|
-
strokeColor: tool.defaults.strokeColor ?? "#000000",
|
|
1302
|
-
strokeStyle: tool.defaults.strokeStyle ?? PdfAnnotationBorderStyle.SOLID,
|
|
1303
|
-
strokeDashArray: tool.defaults.strokeDashArray ?? [],
|
|
1304
|
-
flags: tool.defaults.flags ?? ["print"]
|
|
1305
|
-
};
|
|
1306
|
-
};
|
|
1307
|
-
const commitPolyline = () => {
|
|
1308
|
-
const vertices = getVertices();
|
|
1309
|
-
if (vertices.length < 2) return;
|
|
1310
|
-
const defaults = getDefaults();
|
|
1311
|
-
if (!defaults) return;
|
|
1312
|
-
const rect = lineRectWithEndings(
|
|
1313
|
-
vertices,
|
|
1314
|
-
defaults.strokeWidth,
|
|
1315
|
-
defaults.lineEndings
|
|
1316
|
-
);
|
|
1317
|
-
const anno = {
|
|
1318
|
-
...defaults,
|
|
1319
|
-
vertices,
|
|
1320
|
-
rect,
|
|
1321
|
-
type: PdfAnnotationSubtype.POLYLINE,
|
|
1322
|
-
pageIndex: context.pageIndex,
|
|
1323
|
-
id: uuidV4(),
|
|
1324
|
-
created: /* @__PURE__ */ new Date()
|
|
1113
|
+
...result,
|
|
1114
|
+
vertices: orig.vertices.map((v) => ({ x: v.x + dx, y: v.y + dy }))
|
|
1325
1115
|
};
|
|
1326
|
-
|
|
1327
|
-
|
|
1328
|
-
|
|
1329
|
-
|
|
1330
|
-
|
|
1331
|
-
|
|
1332
|
-
|
|
1333
|
-
|
|
1334
|
-
|
|
1335
|
-
const defaults = getDefaults();
|
|
1336
|
-
if (!defaults) return null;
|
|
1337
|
-
const allPoints = [...vertices, currentPos];
|
|
1338
|
-
const bounds = lineRectWithEndings(
|
|
1339
|
-
allPoints,
|
|
1340
|
-
defaults.strokeWidth,
|
|
1341
|
-
defaults.lineEndings
|
|
1116
|
+
}
|
|
1117
|
+
case "property-update": {
|
|
1118
|
+
const needsRectUpdate = ctx.changes.strokeWidth !== void 0 || ctx.changes.lineEndings !== void 0 || ctx.changes.rotation !== void 0;
|
|
1119
|
+
if (!needsRectUpdate) return ctx.changes;
|
|
1120
|
+
const merged = { ...orig, ...ctx.changes };
|
|
1121
|
+
const tightRect = lineRectWithEndings(
|
|
1122
|
+
merged.vertices,
|
|
1123
|
+
merged.strokeWidth,
|
|
1124
|
+
merged.lineEndings
|
|
1342
1125
|
);
|
|
1343
|
-
|
|
1344
|
-
|
|
1345
|
-
|
|
1346
|
-
|
|
1347
|
-
|
|
1348
|
-
rect:
|
|
1349
|
-
|
|
1350
|
-
|
|
1351
|
-
|
|
1352
|
-
|
|
1353
|
-
|
|
1354
|
-
return {
|
|
1355
|
-
onClick: (pos, evt) => {
|
|
1356
|
-
if (evt.metaKey || evt.ctrlKey) {
|
|
1357
|
-
return;
|
|
1358
|
-
}
|
|
1359
|
-
const clampedPos = clampToPage(pos);
|
|
1360
|
-
const vertices = getVertices();
|
|
1361
|
-
const lastVertex = vertices[vertices.length - 1];
|
|
1362
|
-
if (lastVertex && Math.abs(lastVertex.x - clampedPos.x) < 1 && Math.abs(lastVertex.y - clampedPos.y) < 1) {
|
|
1363
|
-
return;
|
|
1364
|
-
}
|
|
1365
|
-
setVertices([...vertices, clampedPos]);
|
|
1366
|
-
setCurrent(clampedPos);
|
|
1367
|
-
onPreview(getPreview());
|
|
1368
|
-
},
|
|
1369
|
-
onDoubleClick: () => {
|
|
1370
|
-
commitPolyline();
|
|
1371
|
-
},
|
|
1372
|
-
onPointerMove: (pos) => {
|
|
1373
|
-
if (getVertices().length > 0) {
|
|
1374
|
-
const clampedPos = clampToPage(pos);
|
|
1375
|
-
setCurrent(clampedPos);
|
|
1376
|
-
onPreview(getPreview());
|
|
1377
|
-
}
|
|
1378
|
-
},
|
|
1379
|
-
onPointerCancel: () => {
|
|
1380
|
-
setVertices([]);
|
|
1381
|
-
setCurrent(null);
|
|
1382
|
-
onPreview(null);
|
|
1126
|
+
const effectiveRotation = ctx.changes.rotation ?? orig.rotation ?? 0;
|
|
1127
|
+
if (orig.unrotatedRect || ctx.changes.rotation !== void 0) {
|
|
1128
|
+
return {
|
|
1129
|
+
...ctx.changes,
|
|
1130
|
+
unrotatedRect: tightRect,
|
|
1131
|
+
rect: calculateRotatedRectAABBAroundPoint(
|
|
1132
|
+
tightRect,
|
|
1133
|
+
effectiveRotation,
|
|
1134
|
+
resolveAnnotationRotationCenter(orig)
|
|
1135
|
+
)
|
|
1136
|
+
};
|
|
1383
1137
|
}
|
|
1384
|
-
|
|
1138
|
+
return { ...ctx.changes, rect: tightRect };
|
|
1139
|
+
}
|
|
1140
|
+
default:
|
|
1141
|
+
return ctx.changes;
|
|
1385
1142
|
}
|
|
1386
1143
|
};
|
|
1387
1144
|
function convertAABBRectToUnrotatedSpace(newAABBRect, originalAABBRect, originalUnrotatedRect, rotationDegrees) {
|
|
@@ -1932,204 +1689,382 @@ function generateCloudyPolygonPath(vertices, rectOrigin, intensity, lineWidth) {
|
|
|
1932
1689
|
out.close();
|
|
1933
1690
|
return out.build(lineWidth);
|
|
1934
1691
|
}
|
|
1935
|
-
|
|
1936
|
-
|
|
1937
|
-
|
|
1938
|
-
|
|
1939
|
-
|
|
1940
|
-
|
|
1941
|
-
|
|
1942
|
-
|
|
1943
|
-
|
|
1944
|
-
|
|
1945
|
-
|
|
1946
|
-
|
|
1947
|
-
|
|
1948
|
-
|
|
1949
|
-
|
|
1950
|
-
|
|
1951
|
-
|
|
1952
|
-
|
|
1953
|
-
|
|
1954
|
-
|
|
1955
|
-
|
|
1956
|
-
|
|
1692
|
+
function getPolygonPad(intensity, strokeWidth) {
|
|
1693
|
+
if ((intensity ?? 0) > 0) {
|
|
1694
|
+
return getCloudyBorderExtent(intensity, strokeWidth, false);
|
|
1695
|
+
}
|
|
1696
|
+
return strokeWidth / 2;
|
|
1697
|
+
}
|
|
1698
|
+
const patchPolygon = (orig, ctx) => {
|
|
1699
|
+
switch (ctx.type) {
|
|
1700
|
+
case "vertex-edit":
|
|
1701
|
+
if (ctx.changes.vertices && ctx.changes.vertices.length) {
|
|
1702
|
+
const pad = getPolygonPad(orig.cloudyBorderIntensity, orig.strokeWidth);
|
|
1703
|
+
const rawVertices = ctx.changes.vertices;
|
|
1704
|
+
const rawRect = expandRect(rectFromPoints(rawVertices), pad);
|
|
1705
|
+
const compensated = compensateRotatedVertexEdit(orig, rawVertices, rawRect);
|
|
1706
|
+
const rect = expandRect(rectFromPoints(compensated), pad);
|
|
1707
|
+
return {
|
|
1708
|
+
...resolveVertexEditRects(orig, rect),
|
|
1709
|
+
vertices: compensated
|
|
1710
|
+
};
|
|
1711
|
+
}
|
|
1712
|
+
return ctx.changes;
|
|
1713
|
+
case "move": {
|
|
1714
|
+
if (!ctx.changes.rect) return ctx.changes;
|
|
1715
|
+
const { dx, dy, rects } = baseMoveChanges(orig, ctx.changes.rect);
|
|
1957
1716
|
return {
|
|
1958
|
-
...
|
|
1959
|
-
|
|
1960
|
-
opacity: tool.defaults.opacity ?? 1,
|
|
1961
|
-
strokeWidth: tool.defaults.strokeWidth ?? 1,
|
|
1962
|
-
strokeColor: tool.defaults.strokeColor ?? "#000000",
|
|
1963
|
-
strokeStyle: tool.defaults.strokeStyle ?? PdfAnnotationBorderStyle.SOLID,
|
|
1964
|
-
strokeDashArray: tool.defaults.strokeDashArray ?? [],
|
|
1965
|
-
flags: tool.defaults.flags ?? ["print"]
|
|
1966
|
-
};
|
|
1967
|
-
};
|
|
1968
|
-
const commitPolygon = () => {
|
|
1969
|
-
const vertices = getVertices();
|
|
1970
|
-
if (vertices.length < 3) return;
|
|
1971
|
-
const defaults = getDefaults();
|
|
1972
|
-
if (!defaults) return;
|
|
1973
|
-
const intensity = defaults.cloudyBorderIntensity ?? 0;
|
|
1974
|
-
const pad = intensity > 0 ? getCloudyBorderExtent(intensity, defaults.strokeWidth, false) : defaults.strokeWidth / 2;
|
|
1975
|
-
const rect = expandRect(rectFromPoints(vertices), pad);
|
|
1976
|
-
const anno = {
|
|
1977
|
-
...defaults,
|
|
1978
|
-
vertices,
|
|
1979
|
-
rect,
|
|
1980
|
-
type: PdfAnnotationSubtype.POLYGON,
|
|
1981
|
-
pageIndex: context.pageIndex,
|
|
1982
|
-
id: uuidV4(),
|
|
1983
|
-
created: /* @__PURE__ */ new Date(),
|
|
1984
|
-
...intensity > 0 && {
|
|
1985
|
-
rectangleDifferences: { left: pad, top: pad, right: pad, bottom: pad }
|
|
1986
|
-
}
|
|
1717
|
+
...rects,
|
|
1718
|
+
vertices: orig.vertices.map((p) => ({ x: p.x + dx, y: p.y + dy }))
|
|
1987
1719
|
};
|
|
1988
|
-
|
|
1989
|
-
|
|
1990
|
-
|
|
1991
|
-
|
|
1992
|
-
|
|
1993
|
-
|
|
1994
|
-
|
|
1995
|
-
|
|
1996
|
-
if (vertices.length === 0 || !currentPos) return null;
|
|
1997
|
-
const defaults = getDefaults();
|
|
1998
|
-
if (!defaults) return null;
|
|
1999
|
-
const intensity = defaults.cloudyBorderIntensity ?? 0;
|
|
2000
|
-
const pad = intensity > 0 ? getCloudyBorderExtent(intensity, defaults.strokeWidth, false) : defaults.strokeWidth / 2;
|
|
2001
|
-
const allPoints = [...vertices, currentPos];
|
|
2002
|
-
const bounds = expandRect(rectFromPoints(allPoints), pad);
|
|
1720
|
+
}
|
|
1721
|
+
case "resize": {
|
|
1722
|
+
if (!ctx.changes.rect) return ctx.changes;
|
|
1723
|
+
const { scaleX, scaleY, oldRect, resolvedRect, rects } = baseResizeScaling(
|
|
1724
|
+
orig,
|
|
1725
|
+
ctx.changes.rect,
|
|
1726
|
+
ctx.metadata
|
|
1727
|
+
);
|
|
2003
1728
|
return {
|
|
2004
|
-
|
|
2005
|
-
|
|
2006
|
-
|
|
2007
|
-
|
|
2008
|
-
|
|
2009
|
-
vertices,
|
|
2010
|
-
currentVertex: currentPos
|
|
2011
|
-
}
|
|
1729
|
+
...rects,
|
|
1730
|
+
vertices: orig.vertices.map((v) => ({
|
|
1731
|
+
x: resolvedRect.origin.x + (v.x - oldRect.origin.x) * scaleX,
|
|
1732
|
+
y: resolvedRect.origin.y + (v.y - oldRect.origin.y) * scaleY
|
|
1733
|
+
}))
|
|
2012
1734
|
};
|
|
2013
|
-
}
|
|
2014
|
-
|
|
2015
|
-
|
|
2016
|
-
|
|
2017
|
-
|
|
2018
|
-
|
|
2019
|
-
|
|
2020
|
-
|
|
2021
|
-
|
|
2022
|
-
|
|
1735
|
+
}
|
|
1736
|
+
case "rotate": {
|
|
1737
|
+
const result = baseRotateChanges(orig, ctx);
|
|
1738
|
+
if (!result) return ctx.changes;
|
|
1739
|
+
const { dx, dy } = rotateOrbitDelta(orig, result);
|
|
1740
|
+
return {
|
|
1741
|
+
...result,
|
|
1742
|
+
vertices: orig.vertices.map((v) => ({ x: v.x + dx, y: v.y + dy }))
|
|
1743
|
+
};
|
|
1744
|
+
}
|
|
1745
|
+
case "property-update": {
|
|
1746
|
+
const cloudyChanged = ctx.changes.cloudyBorderIntensity !== void 0;
|
|
1747
|
+
const needsRectUpdate = ctx.changes.strokeWidth !== void 0 || ctx.changes.rotation !== void 0 || cloudyChanged;
|
|
1748
|
+
if (!needsRectUpdate) return ctx.changes;
|
|
1749
|
+
const merged = { ...orig, ...ctx.changes };
|
|
1750
|
+
const pad = getPolygonPad(merged.cloudyBorderIntensity, merged.strokeWidth);
|
|
1751
|
+
const tightRect = expandRect(rectFromPoints(merged.vertices), pad);
|
|
1752
|
+
let patch = ctx.changes;
|
|
1753
|
+
const hasCloudy = (orig.cloudyBorderIntensity ?? 0) > 0;
|
|
1754
|
+
if (cloudyChanged || ctx.changes.strokeWidth !== void 0 && hasCloudy) {
|
|
1755
|
+
const intensity = merged.cloudyBorderIntensity ?? 0;
|
|
1756
|
+
if (intensity > 0) {
|
|
1757
|
+
const extent = getCloudyBorderExtent(intensity, merged.strokeWidth, false);
|
|
1758
|
+
patch = {
|
|
1759
|
+
...patch,
|
|
1760
|
+
rectangleDifferences: { left: extent, top: extent, right: extent, bottom: extent }
|
|
1761
|
+
};
|
|
1762
|
+
} else {
|
|
1763
|
+
patch = { ...patch, rectangleDifferences: void 0 };
|
|
2023
1764
|
}
|
|
2024
|
-
|
|
2025
|
-
|
|
2026
|
-
|
|
2027
|
-
|
|
1765
|
+
}
|
|
1766
|
+
const effectiveRotation = ctx.changes.rotation ?? orig.rotation ?? 0;
|
|
1767
|
+
if (orig.unrotatedRect || ctx.changes.rotation !== void 0) {
|
|
1768
|
+
return {
|
|
1769
|
+
...patch,
|
|
1770
|
+
unrotatedRect: tightRect,
|
|
1771
|
+
rect: calculateRotatedRectAABBAroundPoint(
|
|
1772
|
+
tightRect,
|
|
1773
|
+
effectiveRotation,
|
|
1774
|
+
resolveAnnotationRotationCenter(orig)
|
|
1775
|
+
)
|
|
1776
|
+
};
|
|
1777
|
+
}
|
|
1778
|
+
return { ...patch, rect: tightRect };
|
|
1779
|
+
}
|
|
1780
|
+
default:
|
|
1781
|
+
return ctx.changes;
|
|
1782
|
+
}
|
|
1783
|
+
};
|
|
1784
|
+
const patchCircle = (orig, ctx) => {
|
|
1785
|
+
switch (ctx.type) {
|
|
1786
|
+
case "move":
|
|
1787
|
+
if (!ctx.changes.rect) return ctx.changes;
|
|
1788
|
+
return baseMoveChanges(orig, ctx.changes.rect).rects;
|
|
1789
|
+
case "resize":
|
|
1790
|
+
if (!ctx.changes.rect) return ctx.changes;
|
|
1791
|
+
return baseResizeScaling(orig, ctx.changes.rect, ctx.metadata).rects;
|
|
1792
|
+
case "rotate":
|
|
1793
|
+
return baseRotateChanges(orig, ctx) ?? ctx.changes;
|
|
1794
|
+
case "property-update": {
|
|
1795
|
+
let patch = ctx.changes;
|
|
1796
|
+
const cloudyChanged = ctx.changes.cloudyBorderIntensity !== void 0;
|
|
1797
|
+
const strokeChanged = ctx.changes.strokeWidth !== void 0;
|
|
1798
|
+
const hasCloudy = (orig.cloudyBorderIntensity ?? 0) > 0;
|
|
1799
|
+
if (cloudyChanged || strokeChanged && hasCloudy) {
|
|
1800
|
+
const merged = { ...orig, ...ctx.changes };
|
|
1801
|
+
const intensity = merged.cloudyBorderIntensity ?? 0;
|
|
1802
|
+
if (intensity > 0) {
|
|
1803
|
+
const extent = getCloudyBorderExtent(intensity, merged.strokeWidth, true);
|
|
1804
|
+
patch = {
|
|
1805
|
+
...patch,
|
|
1806
|
+
rectangleDifferences: { left: extent, top: extent, right: extent, bottom: extent }
|
|
1807
|
+
};
|
|
1808
|
+
} else {
|
|
1809
|
+
patch = { ...patch, rectangleDifferences: void 0 };
|
|
2028
1810
|
}
|
|
2029
|
-
|
|
2030
|
-
|
|
2031
|
-
|
|
2032
|
-
}
|
|
2033
|
-
|
|
2034
|
-
|
|
2035
|
-
|
|
2036
|
-
|
|
2037
|
-
|
|
2038
|
-
|
|
2039
|
-
|
|
2040
|
-
|
|
1811
|
+
}
|
|
1812
|
+
if (ctx.changes.rotation !== void 0) {
|
|
1813
|
+
patch = { ...patch, ...basePropertyRotationChanges(orig, ctx.changes.rotation) };
|
|
1814
|
+
}
|
|
1815
|
+
return patch;
|
|
1816
|
+
}
|
|
1817
|
+
default:
|
|
1818
|
+
return ctx.changes;
|
|
1819
|
+
}
|
|
1820
|
+
};
|
|
1821
|
+
const patchSquare = (orig, ctx) => {
|
|
1822
|
+
switch (ctx.type) {
|
|
1823
|
+
case "move":
|
|
1824
|
+
if (!ctx.changes.rect) return ctx.changes;
|
|
1825
|
+
return baseMoveChanges(orig, ctx.changes.rect).rects;
|
|
1826
|
+
case "resize":
|
|
1827
|
+
if (!ctx.changes.rect) return ctx.changes;
|
|
1828
|
+
return baseResizeScaling(orig, ctx.changes.rect, ctx.metadata).rects;
|
|
1829
|
+
case "rotate":
|
|
1830
|
+
return baseRotateChanges(orig, ctx) ?? ctx.changes;
|
|
1831
|
+
case "property-update": {
|
|
1832
|
+
let patch = ctx.changes;
|
|
1833
|
+
const cloudyChanged = ctx.changes.cloudyBorderIntensity !== void 0;
|
|
1834
|
+
const strokeChanged = ctx.changes.strokeWidth !== void 0;
|
|
1835
|
+
const hasCloudy = (orig.cloudyBorderIntensity ?? 0) > 0;
|
|
1836
|
+
if (cloudyChanged || strokeChanged && hasCloudy) {
|
|
1837
|
+
const merged = { ...orig, ...ctx.changes };
|
|
1838
|
+
const intensity = merged.cloudyBorderIntensity ?? 0;
|
|
1839
|
+
if (intensity > 0) {
|
|
1840
|
+
const extent = getCloudyBorderExtent(intensity, merged.strokeWidth, false);
|
|
1841
|
+
patch = {
|
|
1842
|
+
...patch,
|
|
1843
|
+
rectangleDifferences: { left: extent, top: extent, right: extent, bottom: extent }
|
|
1844
|
+
};
|
|
1845
|
+
} else {
|
|
1846
|
+
patch = { ...patch, rectangleDifferences: void 0 };
|
|
2041
1847
|
}
|
|
2042
|
-
},
|
|
2043
|
-
onPointerCancel: (_) => {
|
|
2044
|
-
setVertices([]);
|
|
2045
|
-
setCurrent(null);
|
|
2046
|
-
onPreview(null);
|
|
2047
1848
|
}
|
|
2048
|
-
|
|
1849
|
+
if (ctx.changes.rotation !== void 0) {
|
|
1850
|
+
patch = { ...patch, ...basePropertyRotationChanges(orig, ctx.changes.rotation) };
|
|
1851
|
+
}
|
|
1852
|
+
return patch;
|
|
1853
|
+
}
|
|
1854
|
+
default:
|
|
1855
|
+
return ctx.changes;
|
|
2049
1856
|
}
|
|
2050
1857
|
};
|
|
2051
|
-
const
|
|
2052
|
-
|
|
2053
|
-
|
|
2054
|
-
|
|
2055
|
-
|
|
2056
|
-
|
|
2057
|
-
|
|
2058
|
-
|
|
2059
|
-
|
|
2060
|
-
|
|
2061
|
-
|
|
2062
|
-
if (
|
|
2063
|
-
|
|
2064
|
-
...tool.defaults,
|
|
2065
|
-
flags: tool.defaults.flags ?? ["print"],
|
|
2066
|
-
strokeWidth: tool.defaults.strokeWidth ?? 2,
|
|
2067
|
-
strokeColor: tool.defaults.strokeColor ?? "#000000",
|
|
2068
|
-
strokeStyle: tool.defaults.strokeStyle ?? PdfAnnotationBorderStyle.SOLID,
|
|
2069
|
-
strokeDashArray: tool.defaults.strokeDashArray ?? [],
|
|
2070
|
-
color: tool.defaults.color ?? "#000000",
|
|
2071
|
-
opacity: tool.defaults.opacity ?? 1
|
|
2072
|
-
};
|
|
2073
|
-
};
|
|
2074
|
-
const clickDetector = useClickDetector({
|
|
2075
|
-
threshold: 5,
|
|
2076
|
-
getTool,
|
|
2077
|
-
onClickDetected: (pos, tool) => {
|
|
2078
|
-
const defaults = getDefaults();
|
|
2079
|
-
if (!defaults) return;
|
|
2080
|
-
const clickConfig = tool.clickBehavior;
|
|
2081
|
-
if (!(clickConfig == null ? void 0 : clickConfig.enabled)) return;
|
|
2082
|
-
const { width, height } = clickConfig.defaultSize;
|
|
2083
|
-
const halfWidth = width / 2;
|
|
2084
|
-
const halfHeight = height / 2;
|
|
2085
|
-
const x = clamp(pos.x - halfWidth, 0, pageSize.width - width);
|
|
2086
|
-
const y = clamp(pos.y - halfHeight, 0, pageSize.height - height);
|
|
2087
|
-
const strokeWidth = defaults.strokeWidth;
|
|
2088
|
-
const intensity = defaults.cloudyBorderIntensity ?? 0;
|
|
2089
|
-
const pad = intensity > 0 ? getCloudyBorderExtent(intensity, strokeWidth, false) : strokeWidth / 2;
|
|
2090
|
-
const rect = {
|
|
2091
|
-
origin: { x: x - pad, y: y - pad },
|
|
2092
|
-
size: { width: width + 2 * pad, height: height + 2 * pad }
|
|
2093
|
-
};
|
|
2094
|
-
const anno = {
|
|
2095
|
-
...defaults,
|
|
2096
|
-
type: PdfAnnotationSubtype.SQUARE,
|
|
2097
|
-
created: /* @__PURE__ */ new Date(),
|
|
2098
|
-
id: uuidV4(),
|
|
2099
|
-
pageIndex,
|
|
2100
|
-
rect,
|
|
2101
|
-
...intensity > 0 && {
|
|
2102
|
-
rectangleDifferences: { left: pad, top: pad, right: pad, bottom: pad }
|
|
2103
|
-
}
|
|
2104
|
-
};
|
|
2105
|
-
onCommit(anno);
|
|
1858
|
+
const patchFreeText = (orig, ctx) => {
|
|
1859
|
+
switch (ctx.type) {
|
|
1860
|
+
case "move":
|
|
1861
|
+
if (!ctx.changes.rect) return ctx.changes;
|
|
1862
|
+
return baseMoveChanges(orig, ctx.changes.rect).rects;
|
|
1863
|
+
case "resize":
|
|
1864
|
+
if (!ctx.changes.rect) return ctx.changes;
|
|
1865
|
+
return baseResizeScaling(orig, ctx.changes.rect, ctx.metadata).rects;
|
|
1866
|
+
case "rotate":
|
|
1867
|
+
return baseRotateChanges(orig, ctx) ?? ctx.changes;
|
|
1868
|
+
case "property-update":
|
|
1869
|
+
if (ctx.changes.rotation !== void 0) {
|
|
1870
|
+
return { ...ctx.changes, ...basePropertyRotationChanges(orig, ctx.changes.rotation) };
|
|
2106
1871
|
}
|
|
2107
|
-
|
|
2108
|
-
|
|
2109
|
-
|
|
2110
|
-
|
|
2111
|
-
|
|
2112
|
-
|
|
2113
|
-
|
|
2114
|
-
|
|
1872
|
+
return ctx.changes;
|
|
1873
|
+
default:
|
|
1874
|
+
return ctx.changes;
|
|
1875
|
+
}
|
|
1876
|
+
};
|
|
1877
|
+
const patchStamp = (orig, ctx) => {
|
|
1878
|
+
switch (ctx.type) {
|
|
1879
|
+
case "move":
|
|
1880
|
+
if (!ctx.changes.rect) return ctx.changes;
|
|
1881
|
+
return baseMoveChanges(orig, ctx.changes.rect).rects;
|
|
1882
|
+
case "resize":
|
|
1883
|
+
if (!ctx.changes.rect) return ctx.changes;
|
|
1884
|
+
return baseResizeScaling(orig, ctx.changes.rect, ctx.metadata).rects;
|
|
1885
|
+
case "rotate":
|
|
1886
|
+
return baseRotateChanges(orig, ctx) ?? ctx.changes;
|
|
1887
|
+
case "property-update":
|
|
1888
|
+
if (ctx.changes.rotation !== void 0) {
|
|
1889
|
+
return { ...ctx.changes, ...basePropertyRotationChanges(orig, ctx.changes.rotation) };
|
|
1890
|
+
}
|
|
1891
|
+
return ctx.changes;
|
|
1892
|
+
default:
|
|
1893
|
+
return ctx.changes;
|
|
1894
|
+
}
|
|
1895
|
+
};
|
|
1896
|
+
const index = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
1897
|
+
__proto__: null,
|
|
1898
|
+
LINE_ENDING_HANDLERS,
|
|
1899
|
+
PatchRegistry,
|
|
1900
|
+
applyInsertUpright,
|
|
1901
|
+
calculateAABBFromVertices,
|
|
1902
|
+
calculateRotatedRectAABB,
|
|
1903
|
+
calculateRotatedRectAABBAroundPoint,
|
|
1904
|
+
clampAnnotationToPage,
|
|
1905
|
+
compensateRotatedVertexEdit,
|
|
1906
|
+
createEnding,
|
|
1907
|
+
getRectCenter,
|
|
1908
|
+
lineRectWithEndings,
|
|
1909
|
+
patchCircle,
|
|
1910
|
+
patchFreeText,
|
|
1911
|
+
patchInk,
|
|
1912
|
+
patchLine,
|
|
1913
|
+
patchPolygon,
|
|
1914
|
+
patchPolyline,
|
|
1915
|
+
patchRegistry,
|
|
1916
|
+
patchSquare,
|
|
1917
|
+
patchStamp,
|
|
1918
|
+
resolveAnnotationRotationCenter,
|
|
1919
|
+
resolveRotateRects,
|
|
1920
|
+
resolveVertexEditRects,
|
|
1921
|
+
rotatePointAroundCenter: rotatePointAround,
|
|
1922
|
+
rotateVertices
|
|
1923
|
+
}, Symbol.toStringTag, { value: "Module" }));
|
|
1924
|
+
const COMMENT_SIZE = 24;
|
|
1925
|
+
const textHandlerFactory = {
|
|
1926
|
+
annotationType: PdfAnnotationSubtype.TEXT,
|
|
1927
|
+
create(context) {
|
|
1928
|
+
const { onCommit, getTool, pageSize } = context;
|
|
1929
|
+
return {
|
|
1930
|
+
onPointerDown: (pos) => {
|
|
1931
|
+
const tool = getTool();
|
|
1932
|
+
if (!tool) return;
|
|
1933
|
+
const rect = {
|
|
1934
|
+
origin: { x: pos.x - COMMENT_SIZE / 2, y: pos.y - COMMENT_SIZE / 2 },
|
|
1935
|
+
size: { width: COMMENT_SIZE, height: COMMENT_SIZE }
|
|
1936
|
+
};
|
|
1937
|
+
let anno = {
|
|
1938
|
+
...tool.defaults,
|
|
1939
|
+
rect,
|
|
1940
|
+
type: PdfAnnotationSubtype.TEXT,
|
|
1941
|
+
name: tool.defaults.name ?? PdfAnnotationName.Comment,
|
|
1942
|
+
contents: tool.defaults.contents ?? "",
|
|
1943
|
+
flags: tool.defaults.flags ?? ["print", "noRotate", "noZoom"],
|
|
1944
|
+
pageIndex: context.pageIndex,
|
|
1945
|
+
id: uuidV4(),
|
|
1946
|
+
created: /* @__PURE__ */ new Date()
|
|
1947
|
+
};
|
|
1948
|
+
anno = clampAnnotationToPage(anno, pageSize);
|
|
1949
|
+
onCommit(anno);
|
|
1950
|
+
}
|
|
1951
|
+
};
|
|
1952
|
+
}
|
|
1953
|
+
};
|
|
1954
|
+
function useClickDetector({
|
|
1955
|
+
threshold = 5,
|
|
1956
|
+
getTool,
|
|
1957
|
+
onClickDetected
|
|
1958
|
+
}) {
|
|
1959
|
+
const [getStartPos, setStartPos] = useState(null);
|
|
1960
|
+
const [getHasMoved, setHasMoved] = useState(false);
|
|
1961
|
+
return {
|
|
1962
|
+
onStart: (pos) => {
|
|
1963
|
+
setStartPos(pos);
|
|
1964
|
+
setHasMoved(false);
|
|
1965
|
+
},
|
|
1966
|
+
onMove: (pos) => {
|
|
1967
|
+
const start = getStartPos();
|
|
1968
|
+
if (!start || getHasMoved()) return;
|
|
1969
|
+
const distance2 = Math.sqrt(Math.pow(pos.x - start.x, 2) + Math.pow(pos.y - start.y, 2));
|
|
1970
|
+
if (distance2 > threshold) {
|
|
1971
|
+
setHasMoved(true);
|
|
1972
|
+
}
|
|
1973
|
+
},
|
|
1974
|
+
onEnd: (pos) => {
|
|
1975
|
+
var _a;
|
|
1976
|
+
const start = getStartPos();
|
|
1977
|
+
if (start && !getHasMoved()) {
|
|
1978
|
+
const tool = getTool();
|
|
1979
|
+
if (tool && "clickBehavior" in tool && ((_a = tool.clickBehavior) == null ? void 0 : _a.enabled)) {
|
|
1980
|
+
onClickDetected(pos, tool);
|
|
1981
|
+
}
|
|
1982
|
+
}
|
|
1983
|
+
setStartPos(null);
|
|
1984
|
+
setHasMoved(false);
|
|
1985
|
+
},
|
|
1986
|
+
hasMoved: getHasMoved,
|
|
1987
|
+
reset: () => {
|
|
1988
|
+
setStartPos(null);
|
|
1989
|
+
setHasMoved(false);
|
|
1990
|
+
}
|
|
1991
|
+
};
|
|
1992
|
+
}
|
|
1993
|
+
const freeTextHandlerFactory = {
|
|
1994
|
+
annotationType: PdfAnnotationSubtype.FREETEXT,
|
|
1995
|
+
create(context) {
|
|
1996
|
+
const { onCommit, onPreview, getTool, pageSize, pageIndex, pageRotation } = context;
|
|
1997
|
+
const [getStart, setStart] = useState(null);
|
|
1998
|
+
const clampToPage = (pos) => ({
|
|
1999
|
+
x: clamp(pos.x, 0, pageSize.width),
|
|
2000
|
+
y: clamp(pos.y, 0, pageSize.height)
|
|
2001
|
+
});
|
|
2002
|
+
const getDefaults = () => {
|
|
2003
|
+
const tool = getTool();
|
|
2004
|
+
if (!tool) return null;
|
|
2005
|
+
return {
|
|
2006
|
+
...tool.defaults,
|
|
2007
|
+
fontColor: tool.defaults.fontColor ?? "#000000",
|
|
2008
|
+
opacity: tool.defaults.opacity ?? 1,
|
|
2009
|
+
fontSize: tool.defaults.fontSize ?? 12,
|
|
2010
|
+
fontFamily: tool.defaults.fontFamily ?? PdfStandardFont.Helvetica,
|
|
2011
|
+
color: tool.defaults.color ?? tool.defaults.backgroundColor ?? "transparent",
|
|
2012
|
+
textAlign: tool.defaults.textAlign ?? PdfTextAlignment.Left,
|
|
2013
|
+
verticalAlign: tool.defaults.verticalAlign ?? PdfVerticalAlignment.Top,
|
|
2014
|
+
contents: tool.defaults.contents ?? "Insert text here",
|
|
2015
|
+
flags: tool.defaults.flags ?? ["print"]
|
|
2016
|
+
};
|
|
2017
|
+
};
|
|
2018
|
+
const clickDetector = useClickDetector({
|
|
2019
|
+
threshold: 5,
|
|
2020
|
+
getTool,
|
|
2021
|
+
onClickDetected: (pos, tool) => {
|
|
2022
|
+
var _a;
|
|
2023
|
+
const defaults = getDefaults();
|
|
2024
|
+
if (!defaults) return;
|
|
2025
|
+
const clickConfig = tool.clickBehavior;
|
|
2026
|
+
if (!(clickConfig == null ? void 0 : clickConfig.enabled)) return;
|
|
2027
|
+
const { width, height } = clickConfig.defaultSize;
|
|
2028
|
+
const rect = {
|
|
2029
|
+
origin: { x: pos.x - width / 2, y: pos.y - height / 2 },
|
|
2030
|
+
size: { width, height }
|
|
2031
|
+
};
|
|
2032
|
+
const contents = clickConfig.defaultContent ?? defaults.contents;
|
|
2033
|
+
let anno = {
|
|
2034
|
+
...defaults,
|
|
2035
|
+
contents,
|
|
2036
|
+
type: PdfAnnotationSubtype.FREETEXT,
|
|
2037
|
+
rect,
|
|
2038
|
+
pageIndex,
|
|
2039
|
+
id: uuidV4(),
|
|
2040
|
+
created: /* @__PURE__ */ new Date()
|
|
2041
|
+
};
|
|
2042
|
+
if ((_a = tool.behavior) == null ? void 0 : _a.insertUpright) {
|
|
2043
|
+
anno = applyInsertUpright(anno, pageRotation, false);
|
|
2044
|
+
}
|
|
2045
|
+
anno = clampAnnotationToPage(anno, pageSize);
|
|
2046
|
+
onCommit(anno);
|
|
2047
|
+
}
|
|
2048
|
+
});
|
|
2049
|
+
const getPreview = (current) => {
|
|
2050
|
+
const start = getStart();
|
|
2051
|
+
if (!start) return null;
|
|
2115
2052
|
const defaults = getDefaults();
|
|
2116
2053
|
if (!defaults) return null;
|
|
2117
|
-
const
|
|
2118
|
-
const
|
|
2119
|
-
const
|
|
2054
|
+
const minX = Math.min(start.x, current.x);
|
|
2055
|
+
const minY = Math.min(start.y, current.y);
|
|
2056
|
+
const width = Math.abs(start.x - current.x);
|
|
2057
|
+
const height = Math.abs(start.y - current.y);
|
|
2120
2058
|
const rect = {
|
|
2121
|
-
origin: { x: minX
|
|
2122
|
-
size: { width
|
|
2059
|
+
origin: { x: minX, y: minY },
|
|
2060
|
+
size: { width, height }
|
|
2123
2061
|
};
|
|
2124
2062
|
return {
|
|
2125
|
-
type: PdfAnnotationSubtype.
|
|
2063
|
+
type: PdfAnnotationSubtype.FREETEXT,
|
|
2126
2064
|
bounds: rect,
|
|
2127
2065
|
data: {
|
|
2128
|
-
rect,
|
|
2129
2066
|
...defaults,
|
|
2130
|
-
|
|
2131
|
-
rectangleDifferences: { left: pad, top: pad, right: pad, bottom: pad }
|
|
2132
|
-
}
|
|
2067
|
+
rect
|
|
2133
2068
|
}
|
|
2134
2069
|
};
|
|
2135
2070
|
};
|
|
@@ -2150,39 +2085,41 @@ const squareHandlerFactory = {
|
|
|
2150
2085
|
}
|
|
2151
2086
|
},
|
|
2152
2087
|
onPointerUp: (pos, evt) => {
|
|
2153
|
-
var _a;
|
|
2154
|
-
const
|
|
2155
|
-
if (!
|
|
2088
|
+
var _a, _b;
|
|
2089
|
+
const start = getStart();
|
|
2090
|
+
if (!start) return;
|
|
2156
2091
|
const defaults = getDefaults();
|
|
2157
2092
|
if (!defaults) return;
|
|
2158
2093
|
const clampedPos = clampToPage(pos);
|
|
2159
2094
|
if (!clickDetector.hasMoved()) {
|
|
2160
2095
|
clickDetector.onEnd(clampedPos);
|
|
2161
2096
|
} else {
|
|
2162
|
-
const
|
|
2163
|
-
|
|
2164
|
-
const
|
|
2165
|
-
|
|
2166
|
-
|
|
2167
|
-
|
|
2168
|
-
|
|
2169
|
-
|
|
2170
|
-
|
|
2171
|
-
|
|
2172
|
-
|
|
2173
|
-
|
|
2174
|
-
|
|
2175
|
-
|
|
2176
|
-
|
|
2177
|
-
|
|
2178
|
-
|
|
2179
|
-
|
|
2097
|
+
const minX = Math.min(start.x, clampedPos.x);
|
|
2098
|
+
const minY = Math.min(start.y, clampedPos.y);
|
|
2099
|
+
const width = Math.abs(start.x - clampedPos.x);
|
|
2100
|
+
const height = Math.abs(start.y - clampedPos.y);
|
|
2101
|
+
const rect = {
|
|
2102
|
+
origin: { x: minX, y: minY },
|
|
2103
|
+
size: { width, height }
|
|
2104
|
+
};
|
|
2105
|
+
const tool = getTool();
|
|
2106
|
+
let anno = {
|
|
2107
|
+
...defaults,
|
|
2108
|
+
type: PdfAnnotationSubtype.FREETEXT,
|
|
2109
|
+
rect,
|
|
2110
|
+
pageIndex: context.pageIndex,
|
|
2111
|
+
id: uuidV4(),
|
|
2112
|
+
created: /* @__PURE__ */ new Date()
|
|
2113
|
+
};
|
|
2114
|
+
if ((_a = tool == null ? void 0 : tool.behavior) == null ? void 0 : _a.insertUpright) {
|
|
2115
|
+
anno = applyInsertUpright(anno, pageRotation, true);
|
|
2180
2116
|
}
|
|
2117
|
+
onCommit(anno);
|
|
2181
2118
|
}
|
|
2182
2119
|
setStart(null);
|
|
2183
2120
|
onPreview(null);
|
|
2184
2121
|
clickDetector.reset();
|
|
2185
|
-
(
|
|
2122
|
+
(_b = evt.releasePointerCapture) == null ? void 0 : _b.call(evt);
|
|
2186
2123
|
},
|
|
2187
2124
|
onPointerLeave: (_, evt) => {
|
|
2188
2125
|
var _a;
|
|
@@ -2201,149 +2138,30 @@ const squareHandlerFactory = {
|
|
|
2201
2138
|
};
|
|
2202
2139
|
}
|
|
2203
2140
|
};
|
|
2204
|
-
const
|
|
2205
|
-
|
|
2206
|
-
annotationType: PdfAnnotationSubtype.STAMP,
|
|
2141
|
+
const lineHandlerFactory = {
|
|
2142
|
+
annotationType: PdfAnnotationSubtype.LINE,
|
|
2207
2143
|
create(context) {
|
|
2208
|
-
const {
|
|
2209
|
-
|
|
2210
|
-
|
|
2211
|
-
|
|
2212
|
-
|
|
2213
|
-
|
|
2214
|
-
|
|
2215
|
-
const rect = {
|
|
2216
|
-
origin: { x: pos.x - width / 2, y: pos.y - height / 2 },
|
|
2217
|
-
size: { width, height }
|
|
2218
|
-
};
|
|
2219
|
-
let anno = {
|
|
2220
|
-
...tool.defaults,
|
|
2221
|
-
rect,
|
|
2222
|
-
type: PdfAnnotationSubtype.STAMP,
|
|
2223
|
-
name: tool.defaults.name ?? PdfAnnotationName.Image,
|
|
2224
|
-
subject: tool.defaults.subject ?? "Stamp",
|
|
2225
|
-
flags: tool.defaults.flags ?? ["print"],
|
|
2226
|
-
pageIndex: context.pageIndex,
|
|
2227
|
-
id: uuidV4(),
|
|
2228
|
-
created: /* @__PURE__ */ new Date()
|
|
2229
|
-
};
|
|
2230
|
-
if ((_a = tool.behavior) == null ? void 0 : _a.insertUpright) {
|
|
2231
|
-
anno = applyInsertUpright(anno, pageRotation, false);
|
|
2232
|
-
}
|
|
2233
|
-
anno = clampAnnotationToPage(anno, pageSize);
|
|
2234
|
-
onCommit(anno, ctx);
|
|
2235
|
-
};
|
|
2236
|
-
const commitFromBuffer = (pos, buffer, imageSize) => {
|
|
2237
|
-
const meta = getImageMetadata(buffer);
|
|
2238
|
-
if (!meta || meta.mimeType === "application/pdf") return false;
|
|
2239
|
-
const fitted = fitSizeWithin(meta, pageSize);
|
|
2240
|
-
const width = (imageSize == null ? void 0 : imageSize.width) ?? fitted.width;
|
|
2241
|
-
const height = (imageSize == null ? void 0 : imageSize.height) ?? fitted.height;
|
|
2242
|
-
commitStamp(pos, width, height, { data: buffer });
|
|
2243
|
-
return true;
|
|
2244
|
-
};
|
|
2245
|
-
return {
|
|
2246
|
-
onHandlerActiveStart: () => {
|
|
2247
|
-
const tool = getTool();
|
|
2248
|
-
const imageSrc = tool == null ? void 0 : tool.defaults.imageSrc;
|
|
2249
|
-
if (!imageSrc) return;
|
|
2250
|
-
let entry = imageFetchCache.get(imageSrc);
|
|
2251
|
-
if (!entry) {
|
|
2252
|
-
const promise = fetch(imageSrc).then((res) => res.arrayBuffer()).then((buffer) => {
|
|
2253
|
-
const meta = getImageMetadata(buffer);
|
|
2254
|
-
if (!meta || meta.mimeType === "application/pdf") return null;
|
|
2255
|
-
const fitted = fitSizeWithin(meta, pageSize);
|
|
2256
|
-
const imageSize = tool.defaults.imageSize;
|
|
2257
|
-
return {
|
|
2258
|
-
buffer,
|
|
2259
|
-
width: (imageSize == null ? void 0 : imageSize.width) ?? fitted.width,
|
|
2260
|
-
height: (imageSize == null ? void 0 : imageSize.height) ?? fitted.height
|
|
2261
|
-
};
|
|
2262
|
-
}).catch(() => null);
|
|
2263
|
-
entry = { promise, refs: 1 };
|
|
2264
|
-
imageFetchCache.set(imageSrc, entry);
|
|
2265
|
-
} else {
|
|
2266
|
-
entry.refs++;
|
|
2267
|
-
}
|
|
2268
|
-
entry.promise.then((result) => {
|
|
2269
|
-
if (!result) return;
|
|
2270
|
-
cachedBuffer = result.buffer;
|
|
2271
|
-
cachedSize = { width: result.width, height: result.height };
|
|
2272
|
-
});
|
|
2273
|
-
},
|
|
2274
|
-
onHandlerActiveEnd: () => {
|
|
2275
|
-
const tool = getTool();
|
|
2276
|
-
const imageSrc = tool == null ? void 0 : tool.defaults.imageSrc;
|
|
2277
|
-
if (imageSrc) {
|
|
2278
|
-
const entry = imageFetchCache.get(imageSrc);
|
|
2279
|
-
if (entry && --entry.refs <= 0) {
|
|
2280
|
-
imageFetchCache.delete(imageSrc);
|
|
2281
|
-
}
|
|
2282
|
-
}
|
|
2283
|
-
cachedBuffer = null;
|
|
2284
|
-
cachedSize = null;
|
|
2285
|
-
onPreview(null);
|
|
2286
|
-
},
|
|
2287
|
-
onPointerMove: (pos) => {
|
|
2288
|
-
var _a;
|
|
2289
|
-
const tool = getTool();
|
|
2290
|
-
if (!((_a = tool == null ? void 0 : tool.behavior) == null ? void 0 : _a.showGhost) || !cachedSize || !tool.defaults.imageSrc) return;
|
|
2291
|
-
const rect = {
|
|
2292
|
-
origin: { x: pos.x - cachedSize.width / 2, y: pos.y - cachedSize.height / 2 },
|
|
2293
|
-
size: cachedSize
|
|
2294
|
-
};
|
|
2295
|
-
onPreview({
|
|
2296
|
-
type: PdfAnnotationSubtype.STAMP,
|
|
2297
|
-
bounds: rect,
|
|
2298
|
-
data: { rect, ghostUrl: tool.defaults.imageSrc, pageRotation }
|
|
2299
|
-
});
|
|
2300
|
-
},
|
|
2301
|
-
onPointerDown: (pos) => {
|
|
2302
|
-
const tool = getTool();
|
|
2303
|
-
if (!tool) return;
|
|
2304
|
-
const { imageSrc, imageSize } = tool.defaults;
|
|
2305
|
-
if (imageSrc) {
|
|
2306
|
-
onPreview(null);
|
|
2307
|
-
if (cachedBuffer) {
|
|
2308
|
-
commitFromBuffer(pos, cachedBuffer, imageSize);
|
|
2309
|
-
} else {
|
|
2310
|
-
fetch(imageSrc).then((res) => res.arrayBuffer()).then((buffer) => commitFromBuffer(pos, buffer, imageSize));
|
|
2311
|
-
}
|
|
2312
|
-
} else {
|
|
2313
|
-
services.requestFile({
|
|
2314
|
-
accept: "image/png,image/jpeg",
|
|
2315
|
-
onFile: (file) => {
|
|
2316
|
-
file.arrayBuffer().then((buffer) => commitFromBuffer(pos, buffer));
|
|
2317
|
-
}
|
|
2318
|
-
});
|
|
2319
|
-
}
|
|
2320
|
-
},
|
|
2321
|
-
onPointerLeave: () => {
|
|
2322
|
-
onPreview(null);
|
|
2323
|
-
}
|
|
2324
|
-
};
|
|
2325
|
-
}
|
|
2326
|
-
};
|
|
2327
|
-
const circleHandlerFactory = {
|
|
2328
|
-
annotationType: PdfAnnotationSubtype.CIRCLE,
|
|
2329
|
-
create(context) {
|
|
2330
|
-
const { pageIndex, onCommit, onPreview, getTool, pageSize } = context;
|
|
2331
|
-
const [getStart, setStart] = useState(null);
|
|
2332
|
-
const clampToPage = (pos) => ({
|
|
2333
|
-
x: clamp(pos.x, 0, pageSize.width),
|
|
2334
|
-
y: clamp(pos.y, 0, pageSize.height)
|
|
2335
|
-
});
|
|
2336
|
-
const getDefaults = () => {
|
|
2144
|
+
const { pageIndex, onCommit, onPreview, getTool, pageSize } = context;
|
|
2145
|
+
const [getStart, setStart] = useState(null);
|
|
2146
|
+
const clampToPage = (pos) => ({
|
|
2147
|
+
x: clamp(pos.x, 0, pageSize.width),
|
|
2148
|
+
y: clamp(pos.y, 0, pageSize.height)
|
|
2149
|
+
});
|
|
2150
|
+
const getDefaults = () => {
|
|
2337
2151
|
const tool = getTool();
|
|
2338
2152
|
if (!tool) return null;
|
|
2339
2153
|
return {
|
|
2340
2154
|
...tool.defaults,
|
|
2341
|
-
strokeWidth: tool.defaults.strokeWidth ??
|
|
2342
|
-
|
|
2343
|
-
|
|
2344
|
-
|
|
2155
|
+
strokeWidth: tool.defaults.strokeWidth ?? 1,
|
|
2156
|
+
lineEndings: tool.defaults.lineEndings ?? {
|
|
2157
|
+
start: PdfAnnotationLineEnding.None,
|
|
2158
|
+
end: PdfAnnotationLineEnding.None
|
|
2159
|
+
},
|
|
2345
2160
|
color: tool.defaults.color ?? "#000000",
|
|
2346
2161
|
opacity: tool.defaults.opacity ?? 1,
|
|
2162
|
+
strokeStyle: tool.defaults.strokeStyle ?? PdfAnnotationBorderStyle.SOLID,
|
|
2163
|
+
strokeDashArray: tool.defaults.strokeDashArray ?? [],
|
|
2164
|
+
strokeColor: tool.defaults.strokeColor ?? "#000000",
|
|
2347
2165
|
flags: tool.defaults.flags ?? ["print"]
|
|
2348
2166
|
};
|
|
2349
2167
|
};
|
|
@@ -2355,57 +2173,48 @@ const circleHandlerFactory = {
|
|
|
2355
2173
|
if (!defaults) return;
|
|
2356
2174
|
const clickConfig = tool.clickBehavior;
|
|
2357
2175
|
if (!(clickConfig == null ? void 0 : clickConfig.enabled)) return;
|
|
2358
|
-
const
|
|
2359
|
-
const
|
|
2360
|
-
const
|
|
2361
|
-
const
|
|
2362
|
-
const
|
|
2363
|
-
const
|
|
2364
|
-
const
|
|
2365
|
-
const
|
|
2366
|
-
const
|
|
2367
|
-
|
|
2368
|
-
|
|
2369
|
-
|
|
2370
|
-
|
|
2176
|
+
const angle = clickConfig.defaultAngle ?? 0;
|
|
2177
|
+
const length = clickConfig.defaultLength;
|
|
2178
|
+
const halfLength = length / 2;
|
|
2179
|
+
const startX = pos.x - halfLength * Math.cos(angle);
|
|
2180
|
+
const startY = pos.y - halfLength * Math.sin(angle);
|
|
2181
|
+
const endX = pos.x + halfLength * Math.cos(angle);
|
|
2182
|
+
const endY = pos.y + halfLength * Math.sin(angle);
|
|
2183
|
+
const start = clampToPage({ x: startX, y: startY });
|
|
2184
|
+
const end = clampToPage({ x: endX, y: endY });
|
|
2185
|
+
const rect = lineRectWithEndings(
|
|
2186
|
+
[start, end],
|
|
2187
|
+
defaults.strokeWidth,
|
|
2188
|
+
defaults.lineEndings
|
|
2189
|
+
);
|
|
2190
|
+
onCommit({
|
|
2371
2191
|
...defaults,
|
|
2372
|
-
type: PdfAnnotationSubtype.CIRCLE,
|
|
2373
|
-
created: /* @__PURE__ */ new Date(),
|
|
2374
|
-
id: uuidV4(),
|
|
2375
|
-
pageIndex,
|
|
2376
2192
|
rect,
|
|
2377
|
-
|
|
2378
|
-
|
|
2379
|
-
|
|
2380
|
-
|
|
2381
|
-
|
|
2193
|
+
linePoints: { start, end },
|
|
2194
|
+
pageIndex,
|
|
2195
|
+
id: uuidV4(),
|
|
2196
|
+
created: /* @__PURE__ */ new Date(),
|
|
2197
|
+
type: PdfAnnotationSubtype.LINE
|
|
2198
|
+
});
|
|
2382
2199
|
}
|
|
2383
2200
|
});
|
|
2384
2201
|
const getPreview = (current) => {
|
|
2385
|
-
const
|
|
2386
|
-
if (!
|
|
2387
|
-
const minX = Math.min(p1.x, current.x);
|
|
2388
|
-
const minY = Math.min(p1.y, current.y);
|
|
2389
|
-
const width = Math.abs(p1.x - current.x);
|
|
2390
|
-
const height = Math.abs(p1.y - current.y);
|
|
2202
|
+
const start = getStart();
|
|
2203
|
+
if (!start) return null;
|
|
2391
2204
|
const defaults = getDefaults();
|
|
2392
2205
|
if (!defaults) return null;
|
|
2393
|
-
const
|
|
2394
|
-
|
|
2395
|
-
|
|
2396
|
-
|
|
2397
|
-
|
|
2398
|
-
size: { width: width + 2 * pad, height: height + 2 * pad }
|
|
2399
|
-
};
|
|
2206
|
+
const bounds = lineRectWithEndings(
|
|
2207
|
+
[start, current],
|
|
2208
|
+
defaults.strokeWidth,
|
|
2209
|
+
defaults.lineEndings
|
|
2210
|
+
);
|
|
2400
2211
|
return {
|
|
2401
|
-
type: PdfAnnotationSubtype.
|
|
2402
|
-
bounds
|
|
2212
|
+
type: PdfAnnotationSubtype.LINE,
|
|
2213
|
+
bounds,
|
|
2403
2214
|
data: {
|
|
2404
|
-
rect,
|
|
2405
2215
|
...defaults,
|
|
2406
|
-
|
|
2407
|
-
|
|
2408
|
-
}
|
|
2216
|
+
rect: bounds,
|
|
2217
|
+
linePoints: { start, end: current }
|
|
2409
2218
|
}
|
|
2410
2219
|
};
|
|
2411
2220
|
};
|
|
@@ -2427,33 +2236,30 @@ const circleHandlerFactory = {
|
|
|
2427
2236
|
},
|
|
2428
2237
|
onPointerUp: (pos, evt) => {
|
|
2429
2238
|
var _a;
|
|
2430
|
-
const
|
|
2431
|
-
if (!
|
|
2432
|
-
const defaults = getDefaults();
|
|
2433
|
-
if (!defaults) return;
|
|
2239
|
+
const start = getStart();
|
|
2240
|
+
if (!start) return;
|
|
2434
2241
|
const clampedPos = clampToPage(pos);
|
|
2435
2242
|
if (!clickDetector.hasMoved()) {
|
|
2436
2243
|
clickDetector.onEnd(clampedPos);
|
|
2437
2244
|
} else {
|
|
2438
|
-
const
|
|
2439
|
-
if (!
|
|
2440
|
-
|
|
2441
|
-
|
|
2442
|
-
|
|
2443
|
-
|
|
2444
|
-
|
|
2445
|
-
|
|
2446
|
-
|
|
2245
|
+
const defaults = getDefaults();
|
|
2246
|
+
if (!defaults) return;
|
|
2247
|
+
if (Math.abs(clampedPos.x - start.x) > 2 || Math.abs(clampedPos.y - start.y) > 2) {
|
|
2248
|
+
const rect = lineRectWithEndings(
|
|
2249
|
+
[start, clampedPos],
|
|
2250
|
+
defaults.strokeWidth,
|
|
2251
|
+
defaults.lineEndings
|
|
2252
|
+
);
|
|
2253
|
+
onCommit({
|
|
2254
|
+
...defaults,
|
|
2255
|
+
rect,
|
|
2256
|
+
linePoints: { start, end: clampedPos },
|
|
2257
|
+
pageIndex,
|
|
2258
|
+
id: uuidV4(),
|
|
2447
2259
|
flags: ["print"],
|
|
2448
2260
|
created: /* @__PURE__ */ new Date(),
|
|
2449
|
-
|
|
2450
|
-
|
|
2451
|
-
rect: preview.data.rect,
|
|
2452
|
-
...pad !== void 0 && {
|
|
2453
|
-
rectangleDifferences: { left: pad, top: pad, right: pad, bottom: pad }
|
|
2454
|
-
}
|
|
2455
|
-
};
|
|
2456
|
-
onCommit(anno);
|
|
2261
|
+
type: PdfAnnotationSubtype.LINE
|
|
2262
|
+
});
|
|
2457
2263
|
}
|
|
2458
2264
|
}
|
|
2459
2265
|
setStart(null);
|
|
@@ -2478,11 +2284,12 @@ const circleHandlerFactory = {
|
|
|
2478
2284
|
};
|
|
2479
2285
|
}
|
|
2480
2286
|
};
|
|
2481
|
-
const
|
|
2482
|
-
annotationType: PdfAnnotationSubtype.
|
|
2287
|
+
const polylineHandlerFactory = {
|
|
2288
|
+
annotationType: PdfAnnotationSubtype.POLYLINE,
|
|
2483
2289
|
create(context) {
|
|
2484
|
-
const {
|
|
2485
|
-
const [
|
|
2290
|
+
const { onCommit, onPreview, getTool, pageSize } = context;
|
|
2291
|
+
const [getVertices, setVertices] = useState([]);
|
|
2292
|
+
const [getCurrent, setCurrent] = useState(null);
|
|
2486
2293
|
const clampToPage = (pos) => ({
|
|
2487
2294
|
x: clamp(pos.x, 0, pageSize.width),
|
|
2488
2295
|
y: clamp(pos.y, 0, pageSize.height)
|
|
@@ -2492,11 +2299,236 @@ const linkHandlerFactory = {
|
|
|
2492
2299
|
if (!tool) return null;
|
|
2493
2300
|
return {
|
|
2494
2301
|
...tool.defaults,
|
|
2495
|
-
|
|
2302
|
+
strokeWidth: tool.defaults.strokeWidth ?? 1,
|
|
2303
|
+
lineEndings: tool.defaults.lineEndings ?? {
|
|
2304
|
+
start: PdfAnnotationLineEnding.None,
|
|
2305
|
+
end: PdfAnnotationLineEnding.None
|
|
2306
|
+
},
|
|
2307
|
+
color: tool.defaults.color ?? "#000000",
|
|
2308
|
+
opacity: tool.defaults.opacity ?? 1,
|
|
2309
|
+
strokeColor: tool.defaults.strokeColor ?? "#000000",
|
|
2310
|
+
strokeStyle: tool.defaults.strokeStyle ?? PdfAnnotationBorderStyle.SOLID,
|
|
2311
|
+
strokeDashArray: tool.defaults.strokeDashArray ?? [],
|
|
2312
|
+
flags: tool.defaults.flags ?? ["print"]
|
|
2313
|
+
};
|
|
2314
|
+
};
|
|
2315
|
+
const commitPolyline = () => {
|
|
2316
|
+
const vertices = getVertices();
|
|
2317
|
+
if (vertices.length < 2) return;
|
|
2318
|
+
const defaults = getDefaults();
|
|
2319
|
+
if (!defaults) return;
|
|
2320
|
+
const rect = lineRectWithEndings(
|
|
2321
|
+
vertices,
|
|
2322
|
+
defaults.strokeWidth,
|
|
2323
|
+
defaults.lineEndings
|
|
2324
|
+
);
|
|
2325
|
+
const anno = {
|
|
2326
|
+
...defaults,
|
|
2327
|
+
vertices,
|
|
2328
|
+
rect,
|
|
2329
|
+
type: PdfAnnotationSubtype.POLYLINE,
|
|
2330
|
+
pageIndex: context.pageIndex,
|
|
2331
|
+
id: uuidV4(),
|
|
2332
|
+
created: /* @__PURE__ */ new Date()
|
|
2333
|
+
};
|
|
2334
|
+
onCommit(anno);
|
|
2335
|
+
setVertices([]);
|
|
2336
|
+
setCurrent(null);
|
|
2337
|
+
onPreview(null);
|
|
2338
|
+
};
|
|
2339
|
+
const getPreview = () => {
|
|
2340
|
+
const vertices = getVertices();
|
|
2341
|
+
const currentPos = getCurrent();
|
|
2342
|
+
if (vertices.length === 0 || !currentPos) return null;
|
|
2343
|
+
const defaults = getDefaults();
|
|
2344
|
+
if (!defaults) return null;
|
|
2345
|
+
const allPoints = [...vertices, currentPos];
|
|
2346
|
+
const bounds = lineRectWithEndings(
|
|
2347
|
+
allPoints,
|
|
2348
|
+
defaults.strokeWidth,
|
|
2349
|
+
defaults.lineEndings
|
|
2350
|
+
);
|
|
2351
|
+
return {
|
|
2352
|
+
type: PdfAnnotationSubtype.POLYLINE,
|
|
2353
|
+
bounds,
|
|
2354
|
+
data: {
|
|
2355
|
+
...defaults,
|
|
2356
|
+
rect: bounds,
|
|
2357
|
+
vertices: allPoints,
|
|
2358
|
+
currentVertex: currentPos
|
|
2359
|
+
}
|
|
2360
|
+
};
|
|
2361
|
+
};
|
|
2362
|
+
return {
|
|
2363
|
+
onClick: (pos, evt) => {
|
|
2364
|
+
if (evt.metaKey || evt.ctrlKey) {
|
|
2365
|
+
return;
|
|
2366
|
+
}
|
|
2367
|
+
const clampedPos = clampToPage(pos);
|
|
2368
|
+
const vertices = getVertices();
|
|
2369
|
+
const lastVertex = vertices[vertices.length - 1];
|
|
2370
|
+
if (lastVertex && Math.abs(lastVertex.x - clampedPos.x) < 1 && Math.abs(lastVertex.y - clampedPos.y) < 1) {
|
|
2371
|
+
return;
|
|
2372
|
+
}
|
|
2373
|
+
setVertices([...vertices, clampedPos]);
|
|
2374
|
+
setCurrent(clampedPos);
|
|
2375
|
+
onPreview(getPreview());
|
|
2376
|
+
},
|
|
2377
|
+
onDoubleClick: () => {
|
|
2378
|
+
commitPolyline();
|
|
2379
|
+
},
|
|
2380
|
+
onPointerMove: (pos) => {
|
|
2381
|
+
if (getVertices().length > 0) {
|
|
2382
|
+
const clampedPos = clampToPage(pos);
|
|
2383
|
+
setCurrent(clampedPos);
|
|
2384
|
+
onPreview(getPreview());
|
|
2385
|
+
}
|
|
2386
|
+
},
|
|
2387
|
+
onPointerCancel: () => {
|
|
2388
|
+
setVertices([]);
|
|
2389
|
+
setCurrent(null);
|
|
2390
|
+
onPreview(null);
|
|
2391
|
+
}
|
|
2392
|
+
};
|
|
2393
|
+
}
|
|
2394
|
+
};
|
|
2395
|
+
const HANDLE_SIZE_PX = 14;
|
|
2396
|
+
const polygonHandlerFactory = {
|
|
2397
|
+
annotationType: PdfAnnotationSubtype.POLYGON,
|
|
2398
|
+
create(context) {
|
|
2399
|
+
const { onCommit, onPreview, getTool, scale, pageSize } = context;
|
|
2400
|
+
const [getVertices, setVertices] = useState([]);
|
|
2401
|
+
const [getCurrent, setCurrent] = useState(null);
|
|
2402
|
+
const clampToPage = (pos) => ({
|
|
2403
|
+
x: clamp(pos.x, 0, pageSize.width),
|
|
2404
|
+
y: clamp(pos.y, 0, pageSize.height)
|
|
2405
|
+
});
|
|
2406
|
+
const isInsideStartHandle = (pos) => {
|
|
2407
|
+
const vertices = getVertices();
|
|
2408
|
+
if (vertices.length < 2) return false;
|
|
2409
|
+
const sizePDF = HANDLE_SIZE_PX / scale;
|
|
2410
|
+
const half = sizePDF / 2;
|
|
2411
|
+
const v0 = vertices[0];
|
|
2412
|
+
return pos.x >= v0.x - half && pos.x <= v0.x + half && pos.y >= v0.y - half && pos.y <= v0.y + half;
|
|
2413
|
+
};
|
|
2414
|
+
const getDefaults = () => {
|
|
2415
|
+
const tool = getTool();
|
|
2416
|
+
if (!tool) return null;
|
|
2417
|
+
return {
|
|
2418
|
+
...tool.defaults,
|
|
2419
|
+
color: tool.defaults.color ?? "#000000",
|
|
2420
|
+
opacity: tool.defaults.opacity ?? 1,
|
|
2421
|
+
strokeWidth: tool.defaults.strokeWidth ?? 1,
|
|
2422
|
+
strokeColor: tool.defaults.strokeColor ?? "#000000",
|
|
2423
|
+
strokeStyle: tool.defaults.strokeStyle ?? PdfAnnotationBorderStyle.SOLID,
|
|
2424
|
+
strokeDashArray: tool.defaults.strokeDashArray ?? [],
|
|
2425
|
+
flags: tool.defaults.flags ?? ["print"]
|
|
2426
|
+
};
|
|
2427
|
+
};
|
|
2428
|
+
const commitPolygon = () => {
|
|
2429
|
+
const vertices = getVertices();
|
|
2430
|
+
if (vertices.length < 3) return;
|
|
2431
|
+
const defaults = getDefaults();
|
|
2432
|
+
if (!defaults) return;
|
|
2433
|
+
const intensity = defaults.cloudyBorderIntensity ?? 0;
|
|
2434
|
+
const pad = intensity > 0 ? getCloudyBorderExtent(intensity, defaults.strokeWidth, false) : defaults.strokeWidth / 2;
|
|
2435
|
+
const rect = expandRect(rectFromPoints(vertices), pad);
|
|
2436
|
+
const anno = {
|
|
2437
|
+
...defaults,
|
|
2438
|
+
vertices,
|
|
2439
|
+
rect,
|
|
2440
|
+
type: PdfAnnotationSubtype.POLYGON,
|
|
2441
|
+
pageIndex: context.pageIndex,
|
|
2442
|
+
id: uuidV4(),
|
|
2443
|
+
created: /* @__PURE__ */ new Date(),
|
|
2444
|
+
...intensity > 0 && {
|
|
2445
|
+
rectangleDifferences: { left: pad, top: pad, right: pad, bottom: pad }
|
|
2446
|
+
}
|
|
2447
|
+
};
|
|
2448
|
+
onCommit(anno);
|
|
2449
|
+
setVertices([]);
|
|
2450
|
+
setCurrent(null);
|
|
2451
|
+
onPreview(null);
|
|
2452
|
+
};
|
|
2453
|
+
const getPreview = () => {
|
|
2454
|
+
const vertices = getVertices();
|
|
2455
|
+
const currentPos = getCurrent();
|
|
2456
|
+
if (vertices.length === 0 || !currentPos) return null;
|
|
2457
|
+
const defaults = getDefaults();
|
|
2458
|
+
if (!defaults) return null;
|
|
2459
|
+
const intensity = defaults.cloudyBorderIntensity ?? 0;
|
|
2460
|
+
const pad = intensity > 0 ? getCloudyBorderExtent(intensity, defaults.strokeWidth, false) : defaults.strokeWidth / 2;
|
|
2461
|
+
const allPoints = [...vertices, currentPos];
|
|
2462
|
+
const bounds = expandRect(rectFromPoints(allPoints), pad);
|
|
2463
|
+
return {
|
|
2464
|
+
type: PdfAnnotationSubtype.POLYGON,
|
|
2465
|
+
bounds,
|
|
2466
|
+
data: {
|
|
2467
|
+
...defaults,
|
|
2468
|
+
rect: bounds,
|
|
2469
|
+
vertices,
|
|
2470
|
+
currentVertex: currentPos
|
|
2471
|
+
}
|
|
2472
|
+
};
|
|
2473
|
+
};
|
|
2474
|
+
return {
|
|
2475
|
+
onClick: (pos, evt) => {
|
|
2476
|
+
if (evt.metaKey || evt.ctrlKey) {
|
|
2477
|
+
return;
|
|
2478
|
+
}
|
|
2479
|
+
const clampedPos = clampToPage(pos);
|
|
2480
|
+
if (isInsideStartHandle(clampedPos) && getVertices().length >= 3) {
|
|
2481
|
+
commitPolygon();
|
|
2482
|
+
return;
|
|
2483
|
+
}
|
|
2484
|
+
const vertices = getVertices();
|
|
2485
|
+
const lastVertex = vertices[vertices.length - 1];
|
|
2486
|
+
if (lastVertex && Math.abs(lastVertex.x - clampedPos.x) < 1 && Math.abs(lastVertex.y - clampedPos.y) < 1) {
|
|
2487
|
+
return;
|
|
2488
|
+
}
|
|
2489
|
+
setVertices([...vertices, clampedPos]);
|
|
2490
|
+
setCurrent(clampedPos);
|
|
2491
|
+
onPreview(getPreview());
|
|
2492
|
+
},
|
|
2493
|
+
onDoubleClick: (_) => {
|
|
2494
|
+
commitPolygon();
|
|
2495
|
+
},
|
|
2496
|
+
onPointerMove: (pos) => {
|
|
2497
|
+
if (getVertices().length > 0) {
|
|
2498
|
+
const clampedPos = clampToPage(pos);
|
|
2499
|
+
setCurrent(clampedPos);
|
|
2500
|
+
onPreview(getPreview());
|
|
2501
|
+
}
|
|
2502
|
+
},
|
|
2503
|
+
onPointerCancel: (_) => {
|
|
2504
|
+
setVertices([]);
|
|
2505
|
+
setCurrent(null);
|
|
2506
|
+
onPreview(null);
|
|
2507
|
+
}
|
|
2508
|
+
};
|
|
2509
|
+
}
|
|
2510
|
+
};
|
|
2511
|
+
const squareHandlerFactory = {
|
|
2512
|
+
annotationType: PdfAnnotationSubtype.SQUARE,
|
|
2513
|
+
create(context) {
|
|
2514
|
+
const { pageIndex, onCommit, onPreview, getTool, pageSize } = context;
|
|
2515
|
+
const [getStart, setStart] = useState(null);
|
|
2516
|
+
const clampToPage = (pos) => ({
|
|
2517
|
+
x: clamp(pos.x, 0, pageSize.width),
|
|
2518
|
+
y: clamp(pos.y, 0, pageSize.height)
|
|
2519
|
+
});
|
|
2520
|
+
const getDefaults = () => {
|
|
2521
|
+
const tool = getTool();
|
|
2522
|
+
if (!tool) return null;
|
|
2523
|
+
return {
|
|
2524
|
+
...tool.defaults,
|
|
2525
|
+
flags: tool.defaults.flags ?? ["print"],
|
|
2496
2526
|
strokeWidth: tool.defaults.strokeWidth ?? 2,
|
|
2497
|
-
strokeColor: tool.defaults.strokeColor ?? "#
|
|
2498
|
-
strokeStyle: tool.defaults.strokeStyle ?? PdfAnnotationBorderStyle.
|
|
2499
|
-
strokeDashArray: tool.defaults.strokeDashArray ?? []
|
|
2527
|
+
strokeColor: tool.defaults.strokeColor ?? "#000000",
|
|
2528
|
+
strokeStyle: tool.defaults.strokeStyle ?? PdfAnnotationBorderStyle.SOLID,
|
|
2529
|
+
strokeDashArray: tool.defaults.strokeDashArray ?? [],
|
|
2530
|
+
color: tool.defaults.color ?? "#000000",
|
|
2531
|
+
opacity: tool.defaults.opacity ?? 1
|
|
2500
2532
|
};
|
|
2501
2533
|
};
|
|
2502
2534
|
const clickDetector = useClickDetector({
|
|
@@ -2512,18 +2544,23 @@ const linkHandlerFactory = {
|
|
|
2512
2544
|
const halfHeight = height / 2;
|
|
2513
2545
|
const x = clamp(pos.x - halfWidth, 0, pageSize.width - width);
|
|
2514
2546
|
const y = clamp(pos.y - halfHeight, 0, pageSize.height - height);
|
|
2547
|
+
const strokeWidth = defaults.strokeWidth;
|
|
2548
|
+
const intensity = defaults.cloudyBorderIntensity ?? 0;
|
|
2549
|
+
const pad = intensity > 0 ? getCloudyBorderExtent(intensity, strokeWidth, false) : strokeWidth / 2;
|
|
2515
2550
|
const rect = {
|
|
2516
|
-
origin: { x, y },
|
|
2517
|
-
size: { width, height }
|
|
2551
|
+
origin: { x: x - pad, y: y - pad },
|
|
2552
|
+
size: { width: width + 2 * pad, height: height + 2 * pad }
|
|
2518
2553
|
};
|
|
2519
2554
|
const anno = {
|
|
2520
2555
|
...defaults,
|
|
2521
|
-
type: PdfAnnotationSubtype.
|
|
2522
|
-
target: void 0,
|
|
2556
|
+
type: PdfAnnotationSubtype.SQUARE,
|
|
2523
2557
|
created: /* @__PURE__ */ new Date(),
|
|
2524
2558
|
id: uuidV4(),
|
|
2525
2559
|
pageIndex,
|
|
2526
|
-
rect
|
|
2560
|
+
rect,
|
|
2561
|
+
...intensity > 0 && {
|
|
2562
|
+
rectangleDifferences: { left: pad, top: pad, right: pad, bottom: pad }
|
|
2563
|
+
}
|
|
2527
2564
|
};
|
|
2528
2565
|
onCommit(anno);
|
|
2529
2566
|
}
|
|
@@ -2537,19 +2574,22 @@ const linkHandlerFactory = {
|
|
|
2537
2574
|
const height = Math.abs(p1.y - current.y);
|
|
2538
2575
|
const defaults = getDefaults();
|
|
2539
2576
|
if (!defaults) return null;
|
|
2577
|
+
const strokeWidth = defaults.strokeWidth;
|
|
2578
|
+
const intensity = defaults.cloudyBorderIntensity ?? 0;
|
|
2579
|
+
const pad = intensity > 0 ? getCloudyBorderExtent(intensity, strokeWidth, false) : strokeWidth / 2;
|
|
2540
2580
|
const rect = {
|
|
2541
|
-
origin: { x: minX, y: minY },
|
|
2542
|
-
size: { width, height }
|
|
2581
|
+
origin: { x: minX - pad, y: minY - pad },
|
|
2582
|
+
size: { width: width + 2 * pad, height: height + 2 * pad }
|
|
2543
2583
|
};
|
|
2544
2584
|
return {
|
|
2545
|
-
type: PdfAnnotationSubtype.
|
|
2585
|
+
type: PdfAnnotationSubtype.SQUARE,
|
|
2546
2586
|
bounds: rect,
|
|
2547
2587
|
data: {
|
|
2548
2588
|
rect,
|
|
2549
|
-
|
|
2550
|
-
|
|
2551
|
-
|
|
2552
|
-
|
|
2589
|
+
...defaults,
|
|
2590
|
+
...intensity > 0 && {
|
|
2591
|
+
rectangleDifferences: { left: pad, top: pad, right: pad, bottom: pad }
|
|
2592
|
+
}
|
|
2553
2593
|
}
|
|
2554
2594
|
};
|
|
2555
2595
|
};
|
|
@@ -2579,16 +2619,22 @@ const linkHandlerFactory = {
|
|
|
2579
2619
|
if (!clickDetector.hasMoved()) {
|
|
2580
2620
|
clickDetector.onEnd(clampedPos);
|
|
2581
2621
|
} else {
|
|
2622
|
+
const defaults2 = getDefaults();
|
|
2623
|
+
if (!defaults2) return;
|
|
2582
2624
|
const preview = getPreview(clampedPos);
|
|
2583
2625
|
if (preview) {
|
|
2626
|
+
const intensity = defaults2.cloudyBorderIntensity ?? 0;
|
|
2627
|
+
const pad = intensity > 0 ? getCloudyBorderExtent(intensity, defaults2.strokeWidth, false) : void 0;
|
|
2584
2628
|
const anno = {
|
|
2585
|
-
...
|
|
2586
|
-
type: PdfAnnotationSubtype.
|
|
2587
|
-
target: void 0,
|
|
2629
|
+
...defaults2,
|
|
2630
|
+
type: PdfAnnotationSubtype.SQUARE,
|
|
2588
2631
|
created: /* @__PURE__ */ new Date(),
|
|
2589
2632
|
id: uuidV4(),
|
|
2590
2633
|
pageIndex,
|
|
2591
|
-
rect: preview.data.rect
|
|
2634
|
+
rect: preview.data.rect,
|
|
2635
|
+
...pad !== void 0 && {
|
|
2636
|
+
rectangleDifferences: { left: pad, top: pad, right: pad, bottom: pad }
|
|
2637
|
+
}
|
|
2592
2638
|
};
|
|
2593
2639
|
onCommit(anno);
|
|
2594
2640
|
}
|
|
@@ -2615,585 +2661,547 @@ const linkHandlerFactory = {
|
|
|
2615
2661
|
};
|
|
2616
2662
|
}
|
|
2617
2663
|
};
|
|
2618
|
-
const
|
|
2619
|
-
|
|
2620
|
-
|
|
2621
|
-
|
|
2622
|
-
|
|
2623
|
-
|
|
2624
|
-
|
|
2625
|
-
|
|
2626
|
-
|
|
2627
|
-
|
|
2628
|
-
|
|
2629
|
-
|
|
2630
|
-
|
|
2631
|
-
|
|
2632
|
-
created: /* @__PURE__ */ new Date(),
|
|
2633
|
-
id,
|
|
2634
|
-
...text != null && { custom: { text } }
|
|
2635
|
-
});
|
|
2636
|
-
if ((_a = tool.behavior) == null ? void 0 : _a.selectAfterCreate) {
|
|
2637
|
-
context.selectAnnotation(selection.pageIndex, id);
|
|
2638
|
-
}
|
|
2639
|
-
});
|
|
2640
|
-
}
|
|
2641
|
-
}
|
|
2642
|
-
};
|
|
2643
|
-
function computeCaretRect(lastSegRect) {
|
|
2644
|
-
const lineHeight = lastSegRect.size.height;
|
|
2645
|
-
const height = lineHeight / 2;
|
|
2646
|
-
const width = height;
|
|
2647
|
-
const lineEndX = lastSegRect.origin.x + lastSegRect.size.width;
|
|
2648
|
-
return {
|
|
2649
|
-
origin: {
|
|
2650
|
-
x: lineEndX - width / 2,
|
|
2651
|
-
y: lastSegRect.origin.y + lineHeight / 2
|
|
2652
|
-
},
|
|
2653
|
-
size: { width, height }
|
|
2654
|
-
};
|
|
2655
|
-
}
|
|
2656
|
-
const insertTextSelectionHandler = {
|
|
2657
|
-
toolId: "insertText",
|
|
2658
|
-
handle(context, selections, getText) {
|
|
2659
|
-
const tool = context.getTool();
|
|
2660
|
-
if (!tool) return;
|
|
2661
|
-
const getDefaults = () => ({
|
|
2662
|
-
strokeColor: tool.defaults.strokeColor ?? "#E44234",
|
|
2663
|
-
opacity: tool.defaults.opacity ?? 1,
|
|
2664
|
-
flags: tool.defaults.flags ?? ["print"]
|
|
2665
|
-
});
|
|
2666
|
-
for (const selection of selections) {
|
|
2667
|
-
const lastSegRect = selection.segmentRects[selection.segmentRects.length - 1];
|
|
2668
|
-
if (!lastSegRect) continue;
|
|
2669
|
-
const caretRect = computeCaretRect(lastSegRect);
|
|
2670
|
-
const caretId = uuidV4();
|
|
2671
|
-
const defaults = getDefaults();
|
|
2672
|
-
getText().then((text) => {
|
|
2673
|
-
var _a;
|
|
2674
|
-
context.createAnnotation(selection.pageIndex, {
|
|
2675
|
-
type: PdfAnnotationSubtype.CARET,
|
|
2676
|
-
id: caretId,
|
|
2677
|
-
pageIndex: selection.pageIndex,
|
|
2678
|
-
rect: caretRect,
|
|
2679
|
-
strokeColor: defaults.strokeColor,
|
|
2680
|
-
opacity: defaults.opacity,
|
|
2681
|
-
intent: "Insert",
|
|
2682
|
-
rectangleDifferences: { left: 0.5, top: 0.5, right: 0.5, bottom: 0.5 },
|
|
2683
|
-
created: /* @__PURE__ */ new Date(),
|
|
2684
|
-
flags: defaults.flags,
|
|
2685
|
-
...text != null && { custom: { text } }
|
|
2686
|
-
});
|
|
2687
|
-
if ((_a = tool.behavior) == null ? void 0 : _a.selectAfterCreate) {
|
|
2688
|
-
context.selectAnnotation(selection.pageIndex, caretId);
|
|
2689
|
-
}
|
|
2690
|
-
});
|
|
2691
|
-
}
|
|
2692
|
-
}
|
|
2693
|
-
};
|
|
2694
|
-
const replaceTextSelectionHandler = {
|
|
2695
|
-
toolId: "replaceText",
|
|
2696
|
-
handle(context, selections, getText) {
|
|
2697
|
-
const tool = context.getTool();
|
|
2698
|
-
if (!tool) return;
|
|
2699
|
-
const getDefaults = () => ({
|
|
2700
|
-
strokeColor: tool.defaults.strokeColor ?? "#E44234",
|
|
2701
|
-
opacity: tool.defaults.opacity ?? 1,
|
|
2702
|
-
flags: tool.defaults.flags ?? ["print"]
|
|
2703
|
-
});
|
|
2704
|
-
for (const selection of selections) {
|
|
2705
|
-
const lastSegRect = selection.segmentRects[selection.segmentRects.length - 1];
|
|
2706
|
-
if (!lastSegRect) continue;
|
|
2707
|
-
const caretRect = computeCaretRect(lastSegRect);
|
|
2708
|
-
const caretId = uuidV4();
|
|
2709
|
-
const strikeoutId = uuidV4();
|
|
2710
|
-
const defaults = getDefaults();
|
|
2711
|
-
getText().then((text) => {
|
|
2712
|
-
var _a;
|
|
2713
|
-
context.createAnnotation(selection.pageIndex, {
|
|
2714
|
-
type: PdfAnnotationSubtype.CARET,
|
|
2715
|
-
id: caretId,
|
|
2716
|
-
pageIndex: selection.pageIndex,
|
|
2717
|
-
rect: caretRect,
|
|
2718
|
-
strokeColor: defaults.strokeColor,
|
|
2719
|
-
opacity: defaults.opacity,
|
|
2720
|
-
intent: "Replace",
|
|
2721
|
-
rectangleDifferences: { left: 0.5, top: 0.5, right: 0.5, bottom: 0.5 },
|
|
2722
|
-
created: /* @__PURE__ */ new Date(),
|
|
2723
|
-
flags: defaults.flags
|
|
2724
|
-
});
|
|
2725
|
-
context.createAnnotation(selection.pageIndex, {
|
|
2726
|
-
type: PdfAnnotationSubtype.STRIKEOUT,
|
|
2727
|
-
id: strikeoutId,
|
|
2728
|
-
pageIndex: selection.pageIndex,
|
|
2729
|
-
rect: selection.rect,
|
|
2730
|
-
segmentRects: selection.segmentRects,
|
|
2731
|
-
strokeColor: defaults.strokeColor,
|
|
2732
|
-
opacity: defaults.opacity,
|
|
2733
|
-
intent: "StrikeOutTextEdit",
|
|
2734
|
-
inReplyToId: caretId,
|
|
2735
|
-
replyType: PdfAnnotationReplyType.Group,
|
|
2736
|
-
created: /* @__PURE__ */ new Date(),
|
|
2737
|
-
flags: defaults.flags,
|
|
2738
|
-
...text != null && { custom: { text } }
|
|
2739
|
-
});
|
|
2740
|
-
if ((_a = tool.behavior) == null ? void 0 : _a.selectAfterCreate) {
|
|
2741
|
-
context.selectAnnotation(selection.pageIndex, caretId);
|
|
2742
|
-
}
|
|
2743
|
-
});
|
|
2744
|
-
}
|
|
2745
|
-
}
|
|
2746
|
-
};
|
|
2747
|
-
const patchInk = (original, ctx) => {
|
|
2748
|
-
switch (ctx.type) {
|
|
2749
|
-
case "vertex-edit":
|
|
2750
|
-
return ctx.changes;
|
|
2751
|
-
case "move": {
|
|
2752
|
-
if (!ctx.changes.rect) return ctx.changes;
|
|
2753
|
-
const { dx, dy, rects } = baseMoveChanges(original, ctx.changes.rect);
|
|
2754
|
-
return {
|
|
2755
|
-
...rects,
|
|
2756
|
-
inkList: original.inkList.map((stroke) => ({
|
|
2757
|
-
points: stroke.points.map((p) => ({ x: p.x + dx, y: p.y + dy }))
|
|
2758
|
-
}))
|
|
2759
|
-
};
|
|
2760
|
-
}
|
|
2761
|
-
case "resize": {
|
|
2762
|
-
if (!ctx.changes.rect) return ctx.changes;
|
|
2763
|
-
const { scaleX, scaleY, oldRect, resolvedRect, rects } = baseResizeScaling(
|
|
2764
|
-
original,
|
|
2765
|
-
ctx.changes.rect,
|
|
2766
|
-
ctx.metadata
|
|
2767
|
-
);
|
|
2768
|
-
const inset = (r2, pad) => ({
|
|
2769
|
-
origin: { x: r2.origin.x + pad, y: r2.origin.y + pad },
|
|
2770
|
-
size: {
|
|
2771
|
-
width: Math.max(1, r2.size.width - pad * 2),
|
|
2772
|
-
height: Math.max(1, r2.size.height - pad * 2)
|
|
2773
|
-
}
|
|
2774
|
-
});
|
|
2775
|
-
const resizeEpsilon = 1e-3;
|
|
2776
|
-
const widthChanged = Math.abs(scaleX - 1) > resizeEpsilon;
|
|
2777
|
-
const heightChanged = Math.abs(scaleY - 1) > resizeEpsilon;
|
|
2778
|
-
const strokeScale = widthChanged && !heightChanged ? scaleX : !widthChanged && heightChanged ? scaleY : Math.min(scaleX, scaleY);
|
|
2779
|
-
const rawStrokeWidth = Math.max(1, original.strokeWidth * strokeScale);
|
|
2780
|
-
const maxStrokeWidth = Math.max(
|
|
2781
|
-
1,
|
|
2782
|
-
Math.min(resolvedRect.size.width, resolvedRect.size.height)
|
|
2783
|
-
);
|
|
2784
|
-
const clampedStrokeWidth = Math.min(rawStrokeWidth, maxStrokeWidth);
|
|
2785
|
-
const newStrokeWidth = Number(clampedStrokeWidth.toFixed(1));
|
|
2786
|
-
const innerOld = inset(oldRect, original.strokeWidth / 2);
|
|
2787
|
-
const innerNew = inset(resolvedRect, newStrokeWidth / 2);
|
|
2788
|
-
const sx = innerNew.size.width / Math.max(innerOld.size.width, 1e-6);
|
|
2789
|
-
const sy = innerNew.size.height / Math.max(innerOld.size.height, 1e-6);
|
|
2790
|
-
return {
|
|
2791
|
-
...rects,
|
|
2792
|
-
inkList: original.inkList.map((stroke) => ({
|
|
2793
|
-
points: stroke.points.map((p) => ({
|
|
2794
|
-
x: innerNew.origin.x + (p.x - innerOld.origin.x) * sx,
|
|
2795
|
-
y: innerNew.origin.y + (p.y - innerOld.origin.y) * sy
|
|
2796
|
-
}))
|
|
2797
|
-
})),
|
|
2798
|
-
strokeWidth: newStrokeWidth
|
|
2664
|
+
const imageFetchCache = /* @__PURE__ */ new Map();
|
|
2665
|
+
const stampHandlerFactory = {
|
|
2666
|
+
annotationType: PdfAnnotationSubtype.STAMP,
|
|
2667
|
+
create(context) {
|
|
2668
|
+
const { services, onCommit, onPreview, getTool, pageSize, pageRotation } = context;
|
|
2669
|
+
let cachedBuffer = null;
|
|
2670
|
+
let cachedSize = null;
|
|
2671
|
+
const commitStamp = (pos, width, height, ctx) => {
|
|
2672
|
+
var _a;
|
|
2673
|
+
const tool = getTool();
|
|
2674
|
+
if (!tool) return;
|
|
2675
|
+
const rect = {
|
|
2676
|
+
origin: { x: pos.x - width / 2, y: pos.y - height / 2 },
|
|
2677
|
+
size: { width, height }
|
|
2799
2678
|
};
|
|
2800
|
-
|
|
2801
|
-
|
|
2802
|
-
|
|
2803
|
-
|
|
2804
|
-
|
|
2805
|
-
|
|
2806
|
-
|
|
2807
|
-
|
|
2808
|
-
|
|
2809
|
-
|
|
2679
|
+
let anno = {
|
|
2680
|
+
...tool.defaults,
|
|
2681
|
+
rect,
|
|
2682
|
+
type: PdfAnnotationSubtype.STAMP,
|
|
2683
|
+
name: tool.defaults.name ?? PdfAnnotationName.Image,
|
|
2684
|
+
subject: tool.defaults.subject ?? "Stamp",
|
|
2685
|
+
flags: tool.defaults.flags ?? ["print"],
|
|
2686
|
+
pageIndex: context.pageIndex,
|
|
2687
|
+
id: uuidV4(),
|
|
2688
|
+
created: /* @__PURE__ */ new Date()
|
|
2810
2689
|
};
|
|
2811
|
-
|
|
2812
|
-
|
|
2813
|
-
|
|
2814
|
-
|
|
2815
|
-
|
|
2816
|
-
|
|
2817
|
-
|
|
2818
|
-
const
|
|
2819
|
-
if (
|
|
2820
|
-
|
|
2821
|
-
|
|
2822
|
-
|
|
2823
|
-
|
|
2824
|
-
|
|
2825
|
-
|
|
2826
|
-
|
|
2827
|
-
|
|
2690
|
+
if ((_a = tool.behavior) == null ? void 0 : _a.insertUpright) {
|
|
2691
|
+
anno = applyInsertUpright(anno, pageRotation, false);
|
|
2692
|
+
}
|
|
2693
|
+
anno = clampAnnotationToPage(anno, pageSize);
|
|
2694
|
+
onCommit(anno, ctx);
|
|
2695
|
+
};
|
|
2696
|
+
const commitFromBuffer = (pos, buffer, imageSize) => {
|
|
2697
|
+
const meta = getImageMetadata(buffer);
|
|
2698
|
+
if (!meta || meta.mimeType === "application/pdf") return false;
|
|
2699
|
+
const fitted = fitSizeWithin(meta, pageSize);
|
|
2700
|
+
const width = (imageSize == null ? void 0 : imageSize.width) ?? fitted.width;
|
|
2701
|
+
const height = (imageSize == null ? void 0 : imageSize.height) ?? fitted.height;
|
|
2702
|
+
commitStamp(pos, width, height, { data: buffer });
|
|
2703
|
+
return true;
|
|
2704
|
+
};
|
|
2705
|
+
return {
|
|
2706
|
+
onHandlerActiveStart: () => {
|
|
2707
|
+
const tool = getTool();
|
|
2708
|
+
const imageSrc = tool == null ? void 0 : tool.defaults.imageSrc;
|
|
2709
|
+
if (!imageSrc) return;
|
|
2710
|
+
let entry = imageFetchCache.get(imageSrc);
|
|
2711
|
+
if (!entry) {
|
|
2712
|
+
const promise = fetch(imageSrc).then((res) => res.arrayBuffer()).then((buffer) => {
|
|
2713
|
+
const meta = getImageMetadata(buffer);
|
|
2714
|
+
if (!meta || meta.mimeType === "application/pdf") return null;
|
|
2715
|
+
const fitted = fitSizeWithin(meta, pageSize);
|
|
2716
|
+
const imageSize = tool.defaults.imageSize;
|
|
2717
|
+
return {
|
|
2718
|
+
buffer,
|
|
2719
|
+
width: (imageSize == null ? void 0 : imageSize.width) ?? fitted.width,
|
|
2720
|
+
height: (imageSize == null ? void 0 : imageSize.height) ?? fitted.height
|
|
2721
|
+
};
|
|
2722
|
+
}).catch(() => null);
|
|
2723
|
+
entry = { promise, refs: 1 };
|
|
2724
|
+
imageFetchCache.set(imageSrc, entry);
|
|
2725
|
+
} else {
|
|
2726
|
+
entry.refs++;
|
|
2727
|
+
}
|
|
2728
|
+
entry.promise.then((result) => {
|
|
2729
|
+
if (!result) return;
|
|
2730
|
+
cachedBuffer = result.buffer;
|
|
2731
|
+
cachedSize = { width: result.width, height: result.height };
|
|
2732
|
+
});
|
|
2733
|
+
},
|
|
2734
|
+
onHandlerActiveEnd: () => {
|
|
2735
|
+
const tool = getTool();
|
|
2736
|
+
const imageSrc = tool == null ? void 0 : tool.defaults.imageSrc;
|
|
2737
|
+
if (imageSrc) {
|
|
2738
|
+
const entry = imageFetchCache.get(imageSrc);
|
|
2739
|
+
if (entry && --entry.refs <= 0) {
|
|
2740
|
+
imageFetchCache.delete(imageSrc);
|
|
2741
|
+
}
|
|
2742
|
+
}
|
|
2743
|
+
cachedBuffer = null;
|
|
2744
|
+
cachedSize = null;
|
|
2745
|
+
onPreview(null);
|
|
2746
|
+
},
|
|
2747
|
+
onPointerMove: (pos) => {
|
|
2748
|
+
var _a;
|
|
2749
|
+
const tool = getTool();
|
|
2750
|
+
if (!((_a = tool == null ? void 0 : tool.behavior) == null ? void 0 : _a.showGhost) || !cachedSize || !tool.defaults.imageSrc) return;
|
|
2751
|
+
const rect = {
|
|
2752
|
+
origin: { x: pos.x - cachedSize.width / 2, y: pos.y - cachedSize.height / 2 },
|
|
2753
|
+
size: cachedSize
|
|
2828
2754
|
};
|
|
2755
|
+
onPreview({
|
|
2756
|
+
type: PdfAnnotationSubtype.STAMP,
|
|
2757
|
+
bounds: rect,
|
|
2758
|
+
data: { rect, ghostUrl: tool.defaults.imageSrc, pageRotation }
|
|
2759
|
+
});
|
|
2760
|
+
},
|
|
2761
|
+
onPointerDown: (pos) => {
|
|
2762
|
+
const tool = getTool();
|
|
2763
|
+
if (!tool) return;
|
|
2764
|
+
const { imageSrc, imageSize } = tool.defaults;
|
|
2765
|
+
if (imageSrc) {
|
|
2766
|
+
onPreview(null);
|
|
2767
|
+
if (cachedBuffer) {
|
|
2768
|
+
commitFromBuffer(pos, cachedBuffer, imageSize);
|
|
2769
|
+
} else {
|
|
2770
|
+
fetch(imageSrc).then((res) => res.arrayBuffer()).then((buffer) => commitFromBuffer(pos, buffer, imageSize));
|
|
2771
|
+
}
|
|
2772
|
+
} else {
|
|
2773
|
+
services.requestFile({
|
|
2774
|
+
accept: "image/png,image/jpeg",
|
|
2775
|
+
onFile: (file) => {
|
|
2776
|
+
file.arrayBuffer().then((buffer) => commitFromBuffer(pos, buffer));
|
|
2777
|
+
}
|
|
2778
|
+
});
|
|
2779
|
+
}
|
|
2780
|
+
},
|
|
2781
|
+
onPointerLeave: () => {
|
|
2782
|
+
onPreview(null);
|
|
2829
2783
|
}
|
|
2830
|
-
|
|
2831
|
-
}
|
|
2832
|
-
default:
|
|
2833
|
-
return ctx.changes;
|
|
2784
|
+
};
|
|
2834
2785
|
}
|
|
2835
2786
|
};
|
|
2836
|
-
const
|
|
2837
|
-
|
|
2838
|
-
|
|
2839
|
-
|
|
2840
|
-
|
|
2841
|
-
|
|
2842
|
-
|
|
2843
|
-
|
|
2844
|
-
|
|
2845
|
-
|
|
2846
|
-
|
|
2847
|
-
|
|
2787
|
+
const circleHandlerFactory = {
|
|
2788
|
+
annotationType: PdfAnnotationSubtype.CIRCLE,
|
|
2789
|
+
create(context) {
|
|
2790
|
+
const { pageIndex, onCommit, onPreview, getTool, pageSize } = context;
|
|
2791
|
+
const [getStart, setStart] = useState(null);
|
|
2792
|
+
const clampToPage = (pos) => ({
|
|
2793
|
+
x: clamp(pos.x, 0, pageSize.width),
|
|
2794
|
+
y: clamp(pos.y, 0, pageSize.height)
|
|
2795
|
+
});
|
|
2796
|
+
const getDefaults = () => {
|
|
2797
|
+
const tool = getTool();
|
|
2798
|
+
if (!tool) return null;
|
|
2799
|
+
return {
|
|
2800
|
+
...tool.defaults,
|
|
2801
|
+
strokeWidth: tool.defaults.strokeWidth ?? 2,
|
|
2802
|
+
strokeColor: tool.defaults.strokeColor ?? "#000000",
|
|
2803
|
+
strokeStyle: tool.defaults.strokeStyle ?? PdfAnnotationBorderStyle.SOLID,
|
|
2804
|
+
strokeDashArray: tool.defaults.strokeDashArray ?? [],
|
|
2805
|
+
color: tool.defaults.color ?? "#000000",
|
|
2806
|
+
opacity: tool.defaults.opacity ?? 1,
|
|
2807
|
+
flags: tool.defaults.flags ?? ["print"]
|
|
2808
|
+
};
|
|
2809
|
+
};
|
|
2810
|
+
const clickDetector = useClickDetector({
|
|
2811
|
+
threshold: 5,
|
|
2812
|
+
getTool,
|
|
2813
|
+
onClickDetected: (pos, tool) => {
|
|
2814
|
+
const defaults = getDefaults();
|
|
2815
|
+
if (!defaults) return;
|
|
2816
|
+
const clickConfig = tool.clickBehavior;
|
|
2817
|
+
if (!(clickConfig == null ? void 0 : clickConfig.enabled)) return;
|
|
2818
|
+
const { width, height } = clickConfig.defaultSize;
|
|
2819
|
+
const halfWidth = width / 2;
|
|
2820
|
+
const halfHeight = height / 2;
|
|
2821
|
+
const x = clamp(pos.x - halfWidth, 0, pageSize.width - width);
|
|
2822
|
+
const y = clamp(pos.y - halfHeight, 0, pageSize.height - height);
|
|
2823
|
+
const strokeWidth = defaults.strokeWidth;
|
|
2824
|
+
const intensity = defaults.cloudyBorderIntensity ?? 0;
|
|
2825
|
+
const pad = intensity > 0 ? getCloudyBorderExtent(intensity, strokeWidth, true) : strokeWidth / 2;
|
|
2826
|
+
const rect = {
|
|
2827
|
+
origin: { x: x - pad, y: y - pad },
|
|
2828
|
+
size: { width: width + 2 * pad, height: height + 2 * pad }
|
|
2829
|
+
};
|
|
2830
|
+
const anno = {
|
|
2831
|
+
...defaults,
|
|
2832
|
+
type: PdfAnnotationSubtype.CIRCLE,
|
|
2833
|
+
created: /* @__PURE__ */ new Date(),
|
|
2834
|
+
id: uuidV4(),
|
|
2835
|
+
pageIndex,
|
|
2836
|
+
rect,
|
|
2837
|
+
...intensity > 0 && {
|
|
2838
|
+
rectangleDifferences: { left: pad, top: pad, right: pad, bottom: pad }
|
|
2839
|
+
}
|
|
2848
2840
|
};
|
|
2841
|
+
onCommit(anno);
|
|
2849
2842
|
}
|
|
2850
|
-
|
|
2851
|
-
|
|
2852
|
-
|
|
2853
|
-
|
|
2854
|
-
|
|
2855
|
-
|
|
2856
|
-
|
|
2857
|
-
|
|
2858
|
-
|
|
2859
|
-
|
|
2843
|
+
});
|
|
2844
|
+
const getPreview = (current) => {
|
|
2845
|
+
const p1 = getStart();
|
|
2846
|
+
if (!p1) return null;
|
|
2847
|
+
const minX = Math.min(p1.x, current.x);
|
|
2848
|
+
const minY = Math.min(p1.y, current.y);
|
|
2849
|
+
const width = Math.abs(p1.x - current.x);
|
|
2850
|
+
const height = Math.abs(p1.y - current.y);
|
|
2851
|
+
const defaults = getDefaults();
|
|
2852
|
+
if (!defaults) return null;
|
|
2853
|
+
const strokeWidth = defaults.strokeWidth;
|
|
2854
|
+
const intensity = defaults.cloudyBorderIntensity ?? 0;
|
|
2855
|
+
const pad = intensity > 0 ? getCloudyBorderExtent(intensity, strokeWidth, true) : strokeWidth / 2;
|
|
2856
|
+
const rect = {
|
|
2857
|
+
origin: { x: minX - pad, y: minY - pad },
|
|
2858
|
+
size: { width: width + 2 * pad, height: height + 2 * pad }
|
|
2860
2859
|
};
|
|
2861
|
-
}
|
|
2862
|
-
case "resize": {
|
|
2863
|
-
if (!ctx.changes.rect) return ctx.changes;
|
|
2864
|
-
const { scaleX, scaleY, oldRect, resolvedRect, rects } = baseResizeScaling(
|
|
2865
|
-
orig,
|
|
2866
|
-
ctx.changes.rect,
|
|
2867
|
-
ctx.metadata
|
|
2868
|
-
);
|
|
2869
2860
|
return {
|
|
2870
|
-
|
|
2871
|
-
|
|
2872
|
-
|
|
2873
|
-
|
|
2874
|
-
|
|
2875
|
-
|
|
2876
|
-
|
|
2877
|
-
x: resolvedRect.origin.x + (orig.linePoints.end.x - oldRect.origin.x) * scaleX,
|
|
2878
|
-
y: resolvedRect.origin.y + (orig.linePoints.end.y - oldRect.origin.y) * scaleY
|
|
2861
|
+
type: PdfAnnotationSubtype.CIRCLE,
|
|
2862
|
+
bounds: rect,
|
|
2863
|
+
data: {
|
|
2864
|
+
rect,
|
|
2865
|
+
...defaults,
|
|
2866
|
+
...intensity > 0 && {
|
|
2867
|
+
rectangleDifferences: { left: pad, top: pad, right: pad, bottom: pad }
|
|
2879
2868
|
}
|
|
2880
2869
|
}
|
|
2881
2870
|
};
|
|
2882
|
-
}
|
|
2883
|
-
|
|
2884
|
-
|
|
2885
|
-
|
|
2886
|
-
|
|
2887
|
-
|
|
2888
|
-
|
|
2889
|
-
|
|
2890
|
-
|
|
2891
|
-
|
|
2871
|
+
};
|
|
2872
|
+
return {
|
|
2873
|
+
onPointerDown: (pos, evt) => {
|
|
2874
|
+
var _a;
|
|
2875
|
+
const clampedPos = clampToPage(pos);
|
|
2876
|
+
setStart(clampedPos);
|
|
2877
|
+
clickDetector.onStart(clampedPos);
|
|
2878
|
+
onPreview(getPreview(clampedPos));
|
|
2879
|
+
(_a = evt.setPointerCapture) == null ? void 0 : _a.call(evt);
|
|
2880
|
+
},
|
|
2881
|
+
onPointerMove: (pos) => {
|
|
2882
|
+
const clampedPos = clampToPage(pos);
|
|
2883
|
+
clickDetector.onMove(clampedPos);
|
|
2884
|
+
if (getStart() && clickDetector.hasMoved()) {
|
|
2885
|
+
onPreview(getPreview(clampedPos));
|
|
2892
2886
|
}
|
|
2893
|
-
}
|
|
2894
|
-
|
|
2895
|
-
|
|
2896
|
-
|
|
2897
|
-
|
|
2898
|
-
|
|
2899
|
-
|
|
2900
|
-
|
|
2901
|
-
|
|
2902
|
-
|
|
2903
|
-
|
|
2904
|
-
|
|
2905
|
-
|
|
2906
|
-
|
|
2907
|
-
|
|
2908
|
-
|
|
2909
|
-
|
|
2910
|
-
|
|
2911
|
-
|
|
2912
|
-
|
|
2913
|
-
|
|
2914
|
-
|
|
2887
|
+
},
|
|
2888
|
+
onPointerUp: (pos, evt) => {
|
|
2889
|
+
var _a;
|
|
2890
|
+
const p1 = getStart();
|
|
2891
|
+
if (!p1) return;
|
|
2892
|
+
const defaults = getDefaults();
|
|
2893
|
+
if (!defaults) return;
|
|
2894
|
+
const clampedPos = clampToPage(pos);
|
|
2895
|
+
if (!clickDetector.hasMoved()) {
|
|
2896
|
+
clickDetector.onEnd(clampedPos);
|
|
2897
|
+
} else {
|
|
2898
|
+
const defaults2 = getDefaults();
|
|
2899
|
+
if (!defaults2) return;
|
|
2900
|
+
const preview = getPreview(clampedPos);
|
|
2901
|
+
if (preview) {
|
|
2902
|
+
const intensity = defaults2.cloudyBorderIntensity ?? 0;
|
|
2903
|
+
const pad = intensity > 0 ? getCloudyBorderExtent(intensity, defaults2.strokeWidth, true) : void 0;
|
|
2904
|
+
const anno = {
|
|
2905
|
+
...defaults2,
|
|
2906
|
+
type: PdfAnnotationSubtype.CIRCLE,
|
|
2907
|
+
flags: ["print"],
|
|
2908
|
+
created: /* @__PURE__ */ new Date(),
|
|
2909
|
+
id: uuidV4(),
|
|
2910
|
+
pageIndex,
|
|
2911
|
+
rect: preview.data.rect,
|
|
2912
|
+
...pad !== void 0 && {
|
|
2913
|
+
rectangleDifferences: { left: pad, top: pad, right: pad, bottom: pad }
|
|
2914
|
+
}
|
|
2915
|
+
};
|
|
2916
|
+
onCommit(anno);
|
|
2917
|
+
}
|
|
2918
|
+
}
|
|
2919
|
+
setStart(null);
|
|
2920
|
+
onPreview(null);
|
|
2921
|
+
clickDetector.reset();
|
|
2922
|
+
(_a = evt.releasePointerCapture) == null ? void 0 : _a.call(evt);
|
|
2923
|
+
},
|
|
2924
|
+
onPointerLeave: (_, evt) => {
|
|
2925
|
+
var _a;
|
|
2926
|
+
setStart(null);
|
|
2927
|
+
onPreview(null);
|
|
2928
|
+
clickDetector.reset();
|
|
2929
|
+
(_a = evt.releasePointerCapture) == null ? void 0 : _a.call(evt);
|
|
2930
|
+
},
|
|
2931
|
+
onPointerCancel: (_, evt) => {
|
|
2932
|
+
var _a;
|
|
2933
|
+
setStart(null);
|
|
2934
|
+
onPreview(null);
|
|
2935
|
+
clickDetector.reset();
|
|
2936
|
+
(_a = evt.releasePointerCapture) == null ? void 0 : _a.call(evt);
|
|
2915
2937
|
}
|
|
2916
|
-
|
|
2917
|
-
}
|
|
2918
|
-
default:
|
|
2919
|
-
return ctx.changes;
|
|
2938
|
+
};
|
|
2920
2939
|
}
|
|
2921
2940
|
};
|
|
2922
|
-
const
|
|
2923
|
-
|
|
2924
|
-
|
|
2925
|
-
|
|
2926
|
-
|
|
2927
|
-
|
|
2928
|
-
|
|
2929
|
-
|
|
2930
|
-
|
|
2931
|
-
|
|
2932
|
-
|
|
2933
|
-
|
|
2934
|
-
}
|
|
2935
|
-
return ctx.changes;
|
|
2936
|
-
case "move": {
|
|
2937
|
-
if (!ctx.changes.rect) return ctx.changes;
|
|
2938
|
-
const { dx, dy, rects } = baseMoveChanges(orig, ctx.changes.rect);
|
|
2939
|
-
return {
|
|
2940
|
-
...rects,
|
|
2941
|
-
vertices: orig.vertices.map((p) => ({ x: p.x + dx, y: p.y + dy }))
|
|
2942
|
-
};
|
|
2943
|
-
}
|
|
2944
|
-
case "resize": {
|
|
2945
|
-
if (!ctx.changes.rect) return ctx.changes;
|
|
2946
|
-
const { scaleX, scaleY, oldRect, resolvedRect, rects } = baseResizeScaling(
|
|
2947
|
-
orig,
|
|
2948
|
-
ctx.changes.rect,
|
|
2949
|
-
ctx.metadata
|
|
2950
|
-
);
|
|
2951
|
-
return {
|
|
2952
|
-
...rects,
|
|
2953
|
-
vertices: orig.vertices.map((v) => ({
|
|
2954
|
-
x: resolvedRect.origin.x + (v.x - oldRect.origin.x) * scaleX,
|
|
2955
|
-
y: resolvedRect.origin.y + (v.y - oldRect.origin.y) * scaleY
|
|
2956
|
-
}))
|
|
2957
|
-
};
|
|
2958
|
-
}
|
|
2959
|
-
case "rotate": {
|
|
2960
|
-
const result = baseRotateChanges(orig, ctx);
|
|
2961
|
-
if (!result) return ctx.changes;
|
|
2962
|
-
const { dx, dy } = rotateOrbitDelta(orig, result);
|
|
2941
|
+
const linkHandlerFactory = {
|
|
2942
|
+
annotationType: PdfAnnotationSubtype.LINK,
|
|
2943
|
+
create(context) {
|
|
2944
|
+
const { pageIndex, onCommit, onPreview, getTool, pageSize } = context;
|
|
2945
|
+
const [getStart, setStart] = useState(null);
|
|
2946
|
+
const clampToPage = (pos) => ({
|
|
2947
|
+
x: clamp(pos.x, 0, pageSize.width),
|
|
2948
|
+
y: clamp(pos.y, 0, pageSize.height)
|
|
2949
|
+
});
|
|
2950
|
+
const getDefaults = () => {
|
|
2951
|
+
const tool = getTool();
|
|
2952
|
+
if (!tool) return null;
|
|
2963
2953
|
return {
|
|
2964
|
-
...
|
|
2965
|
-
|
|
2954
|
+
...tool.defaults,
|
|
2955
|
+
flags: tool.defaults.flags ?? ["print"],
|
|
2956
|
+
strokeWidth: tool.defaults.strokeWidth ?? 2,
|
|
2957
|
+
strokeColor: tool.defaults.strokeColor ?? "#0000FF",
|
|
2958
|
+
strokeStyle: tool.defaults.strokeStyle ?? PdfAnnotationBorderStyle.UNDERLINE,
|
|
2959
|
+
strokeDashArray: tool.defaults.strokeDashArray ?? []
|
|
2966
2960
|
};
|
|
2967
|
-
}
|
|
2968
|
-
|
|
2969
|
-
|
|
2970
|
-
|
|
2971
|
-
|
|
2972
|
-
|
|
2973
|
-
|
|
2974
|
-
|
|
2975
|
-
|
|
2976
|
-
|
|
2977
|
-
|
|
2978
|
-
|
|
2979
|
-
|
|
2980
|
-
|
|
2981
|
-
|
|
2982
|
-
|
|
2983
|
-
|
|
2984
|
-
effectiveRotation,
|
|
2985
|
-
resolveAnnotationRotationCenter(orig)
|
|
2986
|
-
)
|
|
2961
|
+
};
|
|
2962
|
+
const clickDetector = useClickDetector({
|
|
2963
|
+
threshold: 5,
|
|
2964
|
+
getTool,
|
|
2965
|
+
onClickDetected: (pos, tool) => {
|
|
2966
|
+
const defaults = getDefaults();
|
|
2967
|
+
if (!defaults) return;
|
|
2968
|
+
const clickConfig = tool.clickBehavior;
|
|
2969
|
+
if (!(clickConfig == null ? void 0 : clickConfig.enabled)) return;
|
|
2970
|
+
const { width, height } = clickConfig.defaultSize;
|
|
2971
|
+
const halfWidth = width / 2;
|
|
2972
|
+
const halfHeight = height / 2;
|
|
2973
|
+
const x = clamp(pos.x - halfWidth, 0, pageSize.width - width);
|
|
2974
|
+
const y = clamp(pos.y - halfHeight, 0, pageSize.height - height);
|
|
2975
|
+
const rect = {
|
|
2976
|
+
origin: { x, y },
|
|
2977
|
+
size: { width, height }
|
|
2987
2978
|
};
|
|
2988
|
-
|
|
2989
|
-
|
|
2990
|
-
|
|
2991
|
-
|
|
2992
|
-
|
|
2993
|
-
|
|
2994
|
-
|
|
2995
|
-
|
|
2996
|
-
if ((intensity ?? 0) > 0) {
|
|
2997
|
-
return getCloudyBorderExtent(intensity, strokeWidth, false);
|
|
2998
|
-
}
|
|
2999
|
-
return strokeWidth / 2;
|
|
3000
|
-
}
|
|
3001
|
-
const patchPolygon = (orig, ctx) => {
|
|
3002
|
-
switch (ctx.type) {
|
|
3003
|
-
case "vertex-edit":
|
|
3004
|
-
if (ctx.changes.vertices && ctx.changes.vertices.length) {
|
|
3005
|
-
const pad = getPolygonPad(orig.cloudyBorderIntensity, orig.strokeWidth);
|
|
3006
|
-
const rawVertices = ctx.changes.vertices;
|
|
3007
|
-
const rawRect = expandRect(rectFromPoints(rawVertices), pad);
|
|
3008
|
-
const compensated = compensateRotatedVertexEdit(orig, rawVertices, rawRect);
|
|
3009
|
-
const rect = expandRect(rectFromPoints(compensated), pad);
|
|
3010
|
-
return {
|
|
3011
|
-
...resolveVertexEditRects(orig, rect),
|
|
3012
|
-
vertices: compensated
|
|
2979
|
+
const anno = {
|
|
2980
|
+
...defaults,
|
|
2981
|
+
type: PdfAnnotationSubtype.LINK,
|
|
2982
|
+
target: void 0,
|
|
2983
|
+
created: /* @__PURE__ */ new Date(),
|
|
2984
|
+
id: uuidV4(),
|
|
2985
|
+
pageIndex,
|
|
2986
|
+
rect
|
|
3013
2987
|
};
|
|
2988
|
+
onCommit(anno);
|
|
3014
2989
|
}
|
|
3015
|
-
|
|
3016
|
-
|
|
3017
|
-
|
|
3018
|
-
|
|
3019
|
-
|
|
3020
|
-
|
|
3021
|
-
|
|
3022
|
-
|
|
3023
|
-
|
|
3024
|
-
|
|
3025
|
-
|
|
3026
|
-
|
|
3027
|
-
|
|
3028
|
-
ctx.changes.rect,
|
|
3029
|
-
ctx.metadata
|
|
3030
|
-
);
|
|
3031
|
-
return {
|
|
3032
|
-
...rects,
|
|
3033
|
-
vertices: orig.vertices.map((v) => ({
|
|
3034
|
-
x: resolvedRect.origin.x + (v.x - oldRect.origin.x) * scaleX,
|
|
3035
|
-
y: resolvedRect.origin.y + (v.y - oldRect.origin.y) * scaleY
|
|
3036
|
-
}))
|
|
2990
|
+
});
|
|
2991
|
+
const getPreview = (current) => {
|
|
2992
|
+
const p1 = getStart();
|
|
2993
|
+
if (!p1) return null;
|
|
2994
|
+
const minX = Math.min(p1.x, current.x);
|
|
2995
|
+
const minY = Math.min(p1.y, current.y);
|
|
2996
|
+
const width = Math.abs(p1.x - current.x);
|
|
2997
|
+
const height = Math.abs(p1.y - current.y);
|
|
2998
|
+
const defaults = getDefaults();
|
|
2999
|
+
if (!defaults) return null;
|
|
3000
|
+
const rect = {
|
|
3001
|
+
origin: { x: minX, y: minY },
|
|
3002
|
+
size: { width, height }
|
|
3037
3003
|
};
|
|
3038
|
-
}
|
|
3039
|
-
case "rotate": {
|
|
3040
|
-
const result = baseRotateChanges(orig, ctx);
|
|
3041
|
-
if (!result) return ctx.changes;
|
|
3042
|
-
const { dx, dy } = rotateOrbitDelta(orig, result);
|
|
3043
3004
|
return {
|
|
3044
|
-
|
|
3045
|
-
|
|
3005
|
+
type: PdfAnnotationSubtype.LINK,
|
|
3006
|
+
bounds: rect,
|
|
3007
|
+
data: {
|
|
3008
|
+
rect,
|
|
3009
|
+
strokeColor: defaults.strokeColor,
|
|
3010
|
+
strokeWidth: defaults.strokeWidth,
|
|
3011
|
+
strokeStyle: defaults.strokeStyle,
|
|
3012
|
+
strokeDashArray: defaults.strokeDashArray
|
|
3013
|
+
}
|
|
3046
3014
|
};
|
|
3047
|
-
}
|
|
3048
|
-
|
|
3049
|
-
|
|
3050
|
-
|
|
3051
|
-
|
|
3052
|
-
|
|
3053
|
-
|
|
3054
|
-
|
|
3055
|
-
|
|
3056
|
-
|
|
3057
|
-
|
|
3058
|
-
const
|
|
3059
|
-
|
|
3060
|
-
|
|
3061
|
-
|
|
3062
|
-
|
|
3063
|
-
|
|
3064
|
-
|
|
3015
|
+
};
|
|
3016
|
+
return {
|
|
3017
|
+
onPointerDown: (pos, evt) => {
|
|
3018
|
+
var _a;
|
|
3019
|
+
const clampedPos = clampToPage(pos);
|
|
3020
|
+
setStart(clampedPos);
|
|
3021
|
+
clickDetector.onStart(clampedPos);
|
|
3022
|
+
onPreview(getPreview(clampedPos));
|
|
3023
|
+
(_a = evt.setPointerCapture) == null ? void 0 : _a.call(evt);
|
|
3024
|
+
},
|
|
3025
|
+
onPointerMove: (pos) => {
|
|
3026
|
+
const clampedPos = clampToPage(pos);
|
|
3027
|
+
clickDetector.onMove(clampedPos);
|
|
3028
|
+
if (getStart() && clickDetector.hasMoved()) {
|
|
3029
|
+
onPreview(getPreview(clampedPos));
|
|
3030
|
+
}
|
|
3031
|
+
},
|
|
3032
|
+
onPointerUp: (pos, evt) => {
|
|
3033
|
+
var _a;
|
|
3034
|
+
const p1 = getStart();
|
|
3035
|
+
if (!p1) return;
|
|
3036
|
+
const defaults = getDefaults();
|
|
3037
|
+
if (!defaults) return;
|
|
3038
|
+
const clampedPos = clampToPage(pos);
|
|
3039
|
+
if (!clickDetector.hasMoved()) {
|
|
3040
|
+
clickDetector.onEnd(clampedPos);
|
|
3065
3041
|
} else {
|
|
3066
|
-
|
|
3042
|
+
const preview = getPreview(clampedPos);
|
|
3043
|
+
if (preview) {
|
|
3044
|
+
const anno = {
|
|
3045
|
+
...defaults,
|
|
3046
|
+
type: PdfAnnotationSubtype.LINK,
|
|
3047
|
+
target: void 0,
|
|
3048
|
+
created: /* @__PURE__ */ new Date(),
|
|
3049
|
+
id: uuidV4(),
|
|
3050
|
+
pageIndex,
|
|
3051
|
+
rect: preview.data.rect
|
|
3052
|
+
};
|
|
3053
|
+
onCommit(anno);
|
|
3054
|
+
}
|
|
3067
3055
|
}
|
|
3056
|
+
setStart(null);
|
|
3057
|
+
onPreview(null);
|
|
3058
|
+
clickDetector.reset();
|
|
3059
|
+
(_a = evt.releasePointerCapture) == null ? void 0 : _a.call(evt);
|
|
3060
|
+
},
|
|
3061
|
+
onPointerLeave: (_, evt) => {
|
|
3062
|
+
var _a;
|
|
3063
|
+
setStart(null);
|
|
3064
|
+
onPreview(null);
|
|
3065
|
+
clickDetector.reset();
|
|
3066
|
+
(_a = evt.releasePointerCapture) == null ? void 0 : _a.call(evt);
|
|
3067
|
+
},
|
|
3068
|
+
onPointerCancel: (_, evt) => {
|
|
3069
|
+
var _a;
|
|
3070
|
+
setStart(null);
|
|
3071
|
+
onPreview(null);
|
|
3072
|
+
clickDetector.reset();
|
|
3073
|
+
(_a = evt.releasePointerCapture) == null ? void 0 : _a.call(evt);
|
|
3068
3074
|
}
|
|
3069
|
-
|
|
3070
|
-
if (orig.unrotatedRect || ctx.changes.rotation !== void 0) {
|
|
3071
|
-
return {
|
|
3072
|
-
...patch,
|
|
3073
|
-
unrotatedRect: tightRect,
|
|
3074
|
-
rect: calculateRotatedRectAABBAroundPoint(
|
|
3075
|
-
tightRect,
|
|
3076
|
-
effectiveRotation,
|
|
3077
|
-
resolveAnnotationRotationCenter(orig)
|
|
3078
|
-
)
|
|
3079
|
-
};
|
|
3080
|
-
}
|
|
3081
|
-
return { ...patch, rect: tightRect };
|
|
3082
|
-
}
|
|
3083
|
-
default:
|
|
3084
|
-
return ctx.changes;
|
|
3075
|
+
};
|
|
3085
3076
|
}
|
|
3086
3077
|
};
|
|
3087
|
-
const
|
|
3088
|
-
|
|
3089
|
-
|
|
3090
|
-
|
|
3091
|
-
|
|
3092
|
-
|
|
3093
|
-
|
|
3094
|
-
|
|
3095
|
-
|
|
3096
|
-
|
|
3097
|
-
|
|
3098
|
-
|
|
3099
|
-
|
|
3100
|
-
|
|
3101
|
-
|
|
3102
|
-
|
|
3103
|
-
|
|
3104
|
-
|
|
3105
|
-
if (
|
|
3106
|
-
|
|
3107
|
-
patch = {
|
|
3108
|
-
...patch,
|
|
3109
|
-
rectangleDifferences: { left: extent, top: extent, right: extent, bottom: extent }
|
|
3110
|
-
};
|
|
3111
|
-
} else {
|
|
3112
|
-
patch = { ...patch, rectangleDifferences: void 0 };
|
|
3078
|
+
const textMarkupSelectionHandler = {
|
|
3079
|
+
toolId: "__textMarkup__",
|
|
3080
|
+
handle(context, selections, getText) {
|
|
3081
|
+
const tool = context.getTool();
|
|
3082
|
+
if (!tool) return;
|
|
3083
|
+
for (const selection of selections) {
|
|
3084
|
+
const id = uuidV4();
|
|
3085
|
+
getText().then((text) => {
|
|
3086
|
+
var _a;
|
|
3087
|
+
context.createAnnotation(selection.pageIndex, {
|
|
3088
|
+
...tool.defaults,
|
|
3089
|
+
rect: selection.rect,
|
|
3090
|
+
segmentRects: selection.segmentRects,
|
|
3091
|
+
pageIndex: selection.pageIndex,
|
|
3092
|
+
created: /* @__PURE__ */ new Date(),
|
|
3093
|
+
id,
|
|
3094
|
+
...text != null && { custom: { text } }
|
|
3095
|
+
});
|
|
3096
|
+
if ((_a = tool.behavior) == null ? void 0 : _a.selectAfterCreate) {
|
|
3097
|
+
context.selectAnnotation(selection.pageIndex, id);
|
|
3113
3098
|
}
|
|
3114
|
-
}
|
|
3115
|
-
if (ctx.changes.rotation !== void 0) {
|
|
3116
|
-
patch = { ...patch, ...basePropertyRotationChanges(orig, ctx.changes.rotation) };
|
|
3117
|
-
}
|
|
3118
|
-
return patch;
|
|
3099
|
+
});
|
|
3119
3100
|
}
|
|
3120
|
-
default:
|
|
3121
|
-
return ctx.changes;
|
|
3122
3101
|
}
|
|
3123
3102
|
};
|
|
3124
|
-
|
|
3125
|
-
|
|
3126
|
-
|
|
3127
|
-
|
|
3128
|
-
|
|
3129
|
-
|
|
3130
|
-
|
|
3131
|
-
|
|
3132
|
-
|
|
3133
|
-
|
|
3134
|
-
|
|
3135
|
-
|
|
3136
|
-
|
|
3137
|
-
|
|
3138
|
-
|
|
3139
|
-
|
|
3140
|
-
|
|
3141
|
-
|
|
3142
|
-
|
|
3143
|
-
|
|
3144
|
-
|
|
3145
|
-
|
|
3146
|
-
|
|
3147
|
-
|
|
3148
|
-
|
|
3149
|
-
|
|
3103
|
+
function computeCaretRect(lastSegRect) {
|
|
3104
|
+
const lineHeight = lastSegRect.size.height;
|
|
3105
|
+
const height = lineHeight / 2;
|
|
3106
|
+
const width = height;
|
|
3107
|
+
const lineEndX = lastSegRect.origin.x + lastSegRect.size.width;
|
|
3108
|
+
return {
|
|
3109
|
+
origin: {
|
|
3110
|
+
x: lineEndX - width / 2,
|
|
3111
|
+
y: lastSegRect.origin.y + lineHeight / 2
|
|
3112
|
+
},
|
|
3113
|
+
size: { width, height }
|
|
3114
|
+
};
|
|
3115
|
+
}
|
|
3116
|
+
const insertTextSelectionHandler = {
|
|
3117
|
+
toolId: "insertText",
|
|
3118
|
+
handle(context, selections, getText) {
|
|
3119
|
+
const tool = context.getTool();
|
|
3120
|
+
if (!tool) return;
|
|
3121
|
+
const getDefaults = () => ({
|
|
3122
|
+
strokeColor: tool.defaults.strokeColor ?? "#E44234",
|
|
3123
|
+
opacity: tool.defaults.opacity ?? 1,
|
|
3124
|
+
flags: tool.defaults.flags ?? ["print"]
|
|
3125
|
+
});
|
|
3126
|
+
for (const selection of selections) {
|
|
3127
|
+
const lastSegRect = selection.segmentRects[selection.segmentRects.length - 1];
|
|
3128
|
+
if (!lastSegRect) continue;
|
|
3129
|
+
const caretRect = computeCaretRect(lastSegRect);
|
|
3130
|
+
const caretId = uuidV4();
|
|
3131
|
+
const defaults = getDefaults();
|
|
3132
|
+
getText().then((text) => {
|
|
3133
|
+
var _a;
|
|
3134
|
+
context.createAnnotation(selection.pageIndex, {
|
|
3135
|
+
type: PdfAnnotationSubtype.CARET,
|
|
3136
|
+
id: caretId,
|
|
3137
|
+
pageIndex: selection.pageIndex,
|
|
3138
|
+
rect: caretRect,
|
|
3139
|
+
strokeColor: defaults.strokeColor,
|
|
3140
|
+
opacity: defaults.opacity,
|
|
3141
|
+
intent: "Insert",
|
|
3142
|
+
rectangleDifferences: { left: 0.5, top: 0.5, right: 0.5, bottom: 0.5 },
|
|
3143
|
+
created: /* @__PURE__ */ new Date(),
|
|
3144
|
+
flags: defaults.flags,
|
|
3145
|
+
...text != null && { custom: { text } }
|
|
3146
|
+
});
|
|
3147
|
+
if ((_a = tool.behavior) == null ? void 0 : _a.selectAfterCreate) {
|
|
3148
|
+
context.selectAnnotation(selection.pageIndex, caretId);
|
|
3150
3149
|
}
|
|
3151
|
-
}
|
|
3152
|
-
if (ctx.changes.rotation !== void 0) {
|
|
3153
|
-
patch = { ...patch, ...basePropertyRotationChanges(orig, ctx.changes.rotation) };
|
|
3154
|
-
}
|
|
3155
|
-
return patch;
|
|
3150
|
+
});
|
|
3156
3151
|
}
|
|
3157
|
-
default:
|
|
3158
|
-
return ctx.changes;
|
|
3159
|
-
}
|
|
3160
|
-
};
|
|
3161
|
-
const patchFreeText = (orig, ctx) => {
|
|
3162
|
-
switch (ctx.type) {
|
|
3163
|
-
case "move":
|
|
3164
|
-
if (!ctx.changes.rect) return ctx.changes;
|
|
3165
|
-
return baseMoveChanges(orig, ctx.changes.rect).rects;
|
|
3166
|
-
case "resize":
|
|
3167
|
-
if (!ctx.changes.rect) return ctx.changes;
|
|
3168
|
-
return baseResizeScaling(orig, ctx.changes.rect, ctx.metadata).rects;
|
|
3169
|
-
case "rotate":
|
|
3170
|
-
return baseRotateChanges(orig, ctx) ?? ctx.changes;
|
|
3171
|
-
case "property-update":
|
|
3172
|
-
if (ctx.changes.rotation !== void 0) {
|
|
3173
|
-
return { ...ctx.changes, ...basePropertyRotationChanges(orig, ctx.changes.rotation) };
|
|
3174
|
-
}
|
|
3175
|
-
return ctx.changes;
|
|
3176
|
-
default:
|
|
3177
|
-
return ctx.changes;
|
|
3178
3152
|
}
|
|
3179
3153
|
};
|
|
3180
|
-
const
|
|
3181
|
-
|
|
3182
|
-
|
|
3183
|
-
|
|
3184
|
-
|
|
3185
|
-
|
|
3186
|
-
|
|
3187
|
-
|
|
3188
|
-
|
|
3189
|
-
|
|
3190
|
-
|
|
3191
|
-
|
|
3192
|
-
|
|
3193
|
-
|
|
3194
|
-
|
|
3195
|
-
|
|
3196
|
-
|
|
3154
|
+
const replaceTextSelectionHandler = {
|
|
3155
|
+
toolId: "replaceText",
|
|
3156
|
+
handle(context, selections, getText) {
|
|
3157
|
+
const tool = context.getTool();
|
|
3158
|
+
if (!tool) return;
|
|
3159
|
+
const getDefaults = () => ({
|
|
3160
|
+
strokeColor: tool.defaults.strokeColor ?? "#E44234",
|
|
3161
|
+
opacity: tool.defaults.opacity ?? 1,
|
|
3162
|
+
flags: tool.defaults.flags ?? ["print"]
|
|
3163
|
+
});
|
|
3164
|
+
for (const selection of selections) {
|
|
3165
|
+
const lastSegRect = selection.segmentRects[selection.segmentRects.length - 1];
|
|
3166
|
+
if (!lastSegRect) continue;
|
|
3167
|
+
const caretRect = computeCaretRect(lastSegRect);
|
|
3168
|
+
const caretId = uuidV4();
|
|
3169
|
+
const strikeoutId = uuidV4();
|
|
3170
|
+
const defaults = getDefaults();
|
|
3171
|
+
getText().then((text) => {
|
|
3172
|
+
var _a;
|
|
3173
|
+
context.createAnnotation(selection.pageIndex, {
|
|
3174
|
+
type: PdfAnnotationSubtype.CARET,
|
|
3175
|
+
id: caretId,
|
|
3176
|
+
pageIndex: selection.pageIndex,
|
|
3177
|
+
rect: caretRect,
|
|
3178
|
+
strokeColor: defaults.strokeColor,
|
|
3179
|
+
opacity: defaults.opacity,
|
|
3180
|
+
intent: "Replace",
|
|
3181
|
+
rectangleDifferences: { left: 0.5, top: 0.5, right: 0.5, bottom: 0.5 },
|
|
3182
|
+
created: /* @__PURE__ */ new Date(),
|
|
3183
|
+
flags: defaults.flags
|
|
3184
|
+
});
|
|
3185
|
+
context.createAnnotation(selection.pageIndex, {
|
|
3186
|
+
type: PdfAnnotationSubtype.STRIKEOUT,
|
|
3187
|
+
id: strikeoutId,
|
|
3188
|
+
pageIndex: selection.pageIndex,
|
|
3189
|
+
rect: selection.rect,
|
|
3190
|
+
segmentRects: selection.segmentRects,
|
|
3191
|
+
strokeColor: defaults.strokeColor,
|
|
3192
|
+
opacity: defaults.opacity,
|
|
3193
|
+
intent: "StrikeOutTextEdit",
|
|
3194
|
+
inReplyToId: caretId,
|
|
3195
|
+
replyType: PdfAnnotationReplyType.Group,
|
|
3196
|
+
created: /* @__PURE__ */ new Date(),
|
|
3197
|
+
flags: defaults.flags,
|
|
3198
|
+
...text != null && { custom: { text } }
|
|
3199
|
+
});
|
|
3200
|
+
if ((_a = tool.behavior) == null ? void 0 : _a.selectAfterCreate) {
|
|
3201
|
+
context.selectAnnotation(selection.pageIndex, caretId);
|
|
3202
|
+
}
|
|
3203
|
+
});
|
|
3204
|
+
}
|
|
3197
3205
|
}
|
|
3198
3206
|
};
|
|
3199
3207
|
const textMarkupTools = [
|