kviewer 0.0.3 → 0.0.5
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/README.md +3 -0
- package/dist/module.json +2 -2
- package/dist/runtime/annotation/engine/painter.d.ts +7 -0
- package/dist/runtime/annotation/engine/painter.js +14 -0
- package/dist/runtime/annotation/engine/store.d.ts +5 -0
- package/dist/runtime/annotation/engine/store.js +17 -0
- package/dist/runtime/annotation/engine/tools/free-text.js +3 -1
- package/dist/runtime/annotation/engine/types.d.ts +20 -0
- package/dist/runtime/annotation/pdf-export/export.d.ts +4 -1
- package/dist/runtime/annotation/pdf-export/export.js +101 -4
- package/dist/runtime/annotation/pdf-export/parse_freetext.js +106 -18
- package/dist/runtime/annotation/pdf-export/parse_highlight.js +22 -6
- package/dist/runtime/annotation/pdf-export/parse_ink.js +32 -3
- package/dist/runtime/annotation/pdf-export/parse_line.js +133 -13
- package/dist/runtime/annotation/pdf-import/decode.d.ts +21 -0
- package/dist/runtime/annotation/pdf-import/decode.js +134 -0
- package/dist/runtime/annotation/pdf-import/decode_circle.d.ts +3 -0
- package/dist/runtime/annotation/pdf-import/decode_circle.js +36 -0
- package/dist/runtime/annotation/pdf-import/decode_freetext.d.ts +3 -0
- package/dist/runtime/annotation/pdf-import/decode_freetext.js +87 -0
- package/dist/runtime/annotation/pdf-import/decode_highlight.d.ts +3 -0
- package/dist/runtime/annotation/pdf-import/decode_highlight.js +96 -0
- package/dist/runtime/annotation/pdf-import/decode_ink.d.ts +3 -0
- package/dist/runtime/annotation/pdf-import/decode_ink.js +48 -0
- package/dist/runtime/annotation/pdf-import/decode_line.d.ts +3 -0
- package/dist/runtime/annotation/pdf-import/decode_line.js +48 -0
- package/dist/runtime/annotation/pdf-import/decode_square.d.ts +3 -0
- package/dist/runtime/annotation/pdf-import/decode_square.js +39 -0
- package/dist/runtime/annotation/pdf-import/decode_stamp.d.ts +3 -0
- package/dist/runtime/annotation/pdf-import/decode_stamp.js +38 -0
- package/dist/runtime/annotation/pdf-import/decode_text.d.ts +3 -0
- package/dist/runtime/annotation/pdf-import/decode_text.js +33 -0
- package/dist/runtime/annotation/pdf-import/extract_stamp_appearance.d.ts +23 -0
- package/dist/runtime/annotation/pdf-import/extract_stamp_appearance.js +168 -0
- package/dist/runtime/annotation/pdf-import/types.d.ts +57 -0
- package/dist/runtime/annotation/pdf-import/types.js +25 -0
- package/dist/runtime/annotation/pdf-import/utils.d.ts +48 -0
- package/dist/runtime/annotation/pdf-import/utils.js +250 -0
- package/dist/runtime/assets/kviewer.css +1 -1
- package/dist/runtime/components/AnnotationToolbar.vue +1 -0
- package/dist/runtime/components/FloatingPageIndicator.vue +4 -1
- package/dist/runtime/components/PdfPage.vue +27 -1
- package/dist/runtime/components/Viewer.d.vue.ts +12 -1
- package/dist/runtime/components/Viewer.vue +112 -34
- package/dist/runtime/components/Viewer.vue.d.ts +12 -1
- package/dist/runtime/components/ViewerBar.vue +10 -5
- package/dist/runtime/components/ViewerTabs.d.vue.ts +16 -1
- package/dist/runtime/components/ViewerTabs.vue +42 -12
- package/dist/runtime/components/ViewerTabs.vue.d.ts +16 -1
- package/dist/runtime/components/form-fields/FormCheckbox.vue +37 -1
- package/dist/runtime/components/tools/ActionTools.vue +3 -0
- package/dist/runtime/components/tools/PageInfo.vue +1 -1
- package/dist/runtime/components/tools/SearchTool.vue +3 -1
- package/dist/runtime/components/tools/ZoomControls.vue +3 -0
- package/dist/runtime/composables/shape-detection-utils.d.ts +38 -0
- package/dist/runtime/composables/shape-detection-utils.js +50 -0
- package/dist/runtime/composables/useFormFields.d.ts +3 -1
- package/dist/runtime/composables/useFormFields.js +47 -0
- package/dist/runtime/composables/useShapeDetection.d.ts +24 -0
- package/dist/runtime/composables/useShapeDetection.js +235 -0
- package/dist/runtime/composables/useViewerState.d.ts +2 -0
- package/dist/runtime/composables/useViewerState.js +5 -1
- package/dist/runtime/plugin.d.ts +1 -1
- package/package.json +28 -5
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import Konva from "konva";
|
|
2
|
+
import { AnnotationType } from "../engine/types.js";
|
|
3
|
+
import {
|
|
4
|
+
createAnnotationStore,
|
|
5
|
+
createGhostGroup,
|
|
6
|
+
getAnnotationColor,
|
|
7
|
+
normalizedStrokeWidth,
|
|
8
|
+
rectFromPdfRect
|
|
9
|
+
} from "./utils.js";
|
|
10
|
+
export function decodeSquareAnnotation(annotation, context) {
|
|
11
|
+
const rect = rectFromPdfRect(annotation.rect, context.pageHeight);
|
|
12
|
+
if (!rect || typeof annotation.id !== "string") return null;
|
|
13
|
+
const color = getAnnotationColor(annotation, AnnotationType.RECTANGLE);
|
|
14
|
+
const strokeWidth = normalizedStrokeWidth(annotation, 1);
|
|
15
|
+
const isFilled = strokeWidth <= 0.1;
|
|
16
|
+
const group = createGhostGroup(annotation.id);
|
|
17
|
+
group.add(new Konva.Rect({
|
|
18
|
+
x: rect.x,
|
|
19
|
+
y: rect.y,
|
|
20
|
+
width: rect.width,
|
|
21
|
+
height: rect.height,
|
|
22
|
+
strokeScaleEnabled: false,
|
|
23
|
+
stroke: color,
|
|
24
|
+
strokeWidth,
|
|
25
|
+
fill: isFilled ? color : void 0,
|
|
26
|
+
opacity: isFilled ? 0.5 : 1
|
|
27
|
+
}));
|
|
28
|
+
const store = createAnnotationStore({
|
|
29
|
+
annotation,
|
|
30
|
+
allAnnotations: context.allAnnotations,
|
|
31
|
+
pageNumber: context.pageNumber,
|
|
32
|
+
type: AnnotationType.RECTANGLE,
|
|
33
|
+
group,
|
|
34
|
+
color,
|
|
35
|
+
overrideSubtype: "Square"
|
|
36
|
+
});
|
|
37
|
+
group.destroy();
|
|
38
|
+
return store;
|
|
39
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import Konva from "konva";
|
|
2
|
+
import { AnnotationType } from "../engine/types.js";
|
|
3
|
+
import {
|
|
4
|
+
createAnnotationStore,
|
|
5
|
+
createGhostGroup,
|
|
6
|
+
getAnnotationText,
|
|
7
|
+
rectFromPdfRect
|
|
8
|
+
} from "./utils.js";
|
|
9
|
+
export function decodeStampAnnotation(annotation, context) {
|
|
10
|
+
if (typeof annotation.id !== "string") return null;
|
|
11
|
+
const rect = rectFromPdfRect(annotation.rect, context.pageHeight);
|
|
12
|
+
if (!rect) return null;
|
|
13
|
+
const appearance = context.stampAppearances?.get(annotation.id);
|
|
14
|
+
if (!appearance) {
|
|
15
|
+
console.debug(`[KViewer] Missing stamp appearance for annotation ${annotation.id}`);
|
|
16
|
+
return null;
|
|
17
|
+
}
|
|
18
|
+
const group = createGhostGroup(annotation.id);
|
|
19
|
+
group.add(new Konva.Image({
|
|
20
|
+
x: rect.x,
|
|
21
|
+
y: rect.y,
|
|
22
|
+
width: rect.width > 0 ? rect.width : appearance.width,
|
|
23
|
+
height: rect.height > 0 ? rect.height : appearance.height,
|
|
24
|
+
base64: appearance.dataUrl
|
|
25
|
+
}));
|
|
26
|
+
const store = createAnnotationStore({
|
|
27
|
+
annotation,
|
|
28
|
+
allAnnotations: context.allAnnotations,
|
|
29
|
+
pageNumber: context.pageNumber,
|
|
30
|
+
type: AnnotationType.STAMP,
|
|
31
|
+
group,
|
|
32
|
+
contentsText: getAnnotationText(annotation),
|
|
33
|
+
contentsImage: appearance.dataUrl,
|
|
34
|
+
overrideSubtype: "Stamp"
|
|
35
|
+
});
|
|
36
|
+
group.destroy();
|
|
37
|
+
return store;
|
|
38
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { AnnotationType } from "../engine/types.js";
|
|
2
|
+
import { createDocumentIcon } from "../engine/utils.js";
|
|
3
|
+
import {
|
|
4
|
+
createAnnotationStore,
|
|
5
|
+
createGhostGroup,
|
|
6
|
+
getAnnotationColor,
|
|
7
|
+
getAnnotationText,
|
|
8
|
+
rectFromPdfRect
|
|
9
|
+
} from "./utils.js";
|
|
10
|
+
export function decodeTextAnnotation(annotation, context) {
|
|
11
|
+
if (annotation.inReplyTo) return null;
|
|
12
|
+
const rect = rectFromPdfRect(annotation.rect, context.pageHeight);
|
|
13
|
+
if (!rect || typeof annotation.id !== "string") return null;
|
|
14
|
+
const color = getAnnotationColor(annotation, AnnotationType.NOTE);
|
|
15
|
+
const group = createGhostGroup(annotation.id);
|
|
16
|
+
group.add(...createDocumentIcon({
|
|
17
|
+
x: rect.x,
|
|
18
|
+
y: rect.y,
|
|
19
|
+
fill: color
|
|
20
|
+
}));
|
|
21
|
+
const store = createAnnotationStore({
|
|
22
|
+
annotation,
|
|
23
|
+
allAnnotations: context.allAnnotations,
|
|
24
|
+
pageNumber: context.pageNumber,
|
|
25
|
+
type: AnnotationType.NOTE,
|
|
26
|
+
group,
|
|
27
|
+
color,
|
|
28
|
+
contentsText: getAnnotationText(annotation),
|
|
29
|
+
overrideSubtype: "Text"
|
|
30
|
+
});
|
|
31
|
+
group.destroy();
|
|
32
|
+
return store;
|
|
33
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { PDFPageProxy } from 'pdfjs-dist';
|
|
2
|
+
import { type RawPdfAnnotation, type StampAppearance } from './types.js';
|
|
3
|
+
export interface StampExtractionOptions {
|
|
4
|
+
scale?: number;
|
|
5
|
+
diffThreshold?: number;
|
|
6
|
+
}
|
|
7
|
+
export interface PixelBounds {
|
|
8
|
+
x: number;
|
|
9
|
+
y: number;
|
|
10
|
+
width: number;
|
|
11
|
+
height: number;
|
|
12
|
+
}
|
|
13
|
+
export declare function stampRectToPixelBounds(rect: unknown, pageHeight: number, scale: number, canvasWidth: number, canvasHeight: number): PixelBounds | null;
|
|
14
|
+
export declare function findMaskBounds(mask: Uint8Array, width: number, height: number): PixelBounds | null;
|
|
15
|
+
export declare function computeDiffMask(base: Uint8ClampedArray, annotated: Uint8ClampedArray, width: number, height: number, threshold?: number): {
|
|
16
|
+
mask: Uint8Array;
|
|
17
|
+
bounds: PixelBounds | null;
|
|
18
|
+
};
|
|
19
|
+
export declare function applyMaskOrFallback(annotated: Uint8ClampedArray, mask: Uint8Array): {
|
|
20
|
+
data: Uint8ClampedArray;
|
|
21
|
+
usedMask: boolean;
|
|
22
|
+
};
|
|
23
|
+
export declare function extractStampAppearancesForPage(page: PDFPageProxy, pageHeight: number, annotations: RawPdfAnnotation[], options?: StampExtractionOptions): Promise<Map<string, StampAppearance>>;
|
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
import { PdfjsAnnotationType } from "../engine/types.js";
|
|
2
|
+
import { isNumber } from "./types.js";
|
|
3
|
+
const PDFJS_ANNOTATION_MODE_DISABLE = 0;
|
|
4
|
+
const PDFJS_ANNOTATION_MODE_ENABLE = 1;
|
|
5
|
+
const DEFAULT_RENDER_SCALE = 2;
|
|
6
|
+
const DEFAULT_DIFF_THRESHOLD = 24;
|
|
7
|
+
function normalizedPageRect(rect, pageHeight) {
|
|
8
|
+
if (!Array.isArray(rect) || rect.length < 4) return null;
|
|
9
|
+
const [rx1, ry1, rx2, ry2] = rect;
|
|
10
|
+
if (!isNumber(rx1) || !isNumber(ry1) || !isNumber(rx2) || !isNumber(ry2)) return null;
|
|
11
|
+
const x1 = Math.min(rx1, rx2);
|
|
12
|
+
const x2 = Math.max(rx1, rx2);
|
|
13
|
+
const y1 = Math.min(ry1, ry2);
|
|
14
|
+
const y2 = Math.max(ry1, ry2);
|
|
15
|
+
return {
|
|
16
|
+
x: x1,
|
|
17
|
+
y: pageHeight - y2,
|
|
18
|
+
width: x2 - x1,
|
|
19
|
+
height: y2 - y1
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
export function stampRectToPixelBounds(rect, pageHeight, scale, canvasWidth, canvasHeight) {
|
|
23
|
+
const normalized = normalizedPageRect(rect, pageHeight);
|
|
24
|
+
if (!normalized) return null;
|
|
25
|
+
const left = Math.max(0, Math.floor(normalized.x * scale));
|
|
26
|
+
const top = Math.max(0, Math.floor(normalized.y * scale));
|
|
27
|
+
const right = Math.min(canvasWidth, Math.ceil((normalized.x + normalized.width) * scale));
|
|
28
|
+
const bottom = Math.min(canvasHeight, Math.ceil((normalized.y + normalized.height) * scale));
|
|
29
|
+
const width = Math.max(0, right - left);
|
|
30
|
+
const height = Math.max(0, bottom - top);
|
|
31
|
+
if (width === 0 || height === 0) return null;
|
|
32
|
+
return { x: left, y: top, width, height };
|
|
33
|
+
}
|
|
34
|
+
export function findMaskBounds(mask, width, height) {
|
|
35
|
+
let minX = width;
|
|
36
|
+
let minY = height;
|
|
37
|
+
let maxX = -1;
|
|
38
|
+
let maxY = -1;
|
|
39
|
+
for (let y = 0; y < height; y++) {
|
|
40
|
+
for (let x = 0; x < width; x++) {
|
|
41
|
+
const index = y * width + x;
|
|
42
|
+
if (mask[index] !== 1) continue;
|
|
43
|
+
if (x < minX) minX = x;
|
|
44
|
+
if (y < minY) minY = y;
|
|
45
|
+
if (x > maxX) maxX = x;
|
|
46
|
+
if (y > maxY) maxY = y;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
if (maxX < minX || maxY < minY) return null;
|
|
50
|
+
return {
|
|
51
|
+
x: minX,
|
|
52
|
+
y: minY,
|
|
53
|
+
width: maxX - minX + 1,
|
|
54
|
+
height: maxY - minY + 1
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
export function computeDiffMask(base, annotated, width, height, threshold = DEFAULT_DIFF_THRESHOLD) {
|
|
58
|
+
const pixelCount = width * height;
|
|
59
|
+
const mask = new Uint8Array(pixelCount);
|
|
60
|
+
if (base.length !== annotated.length || base.length !== pixelCount * 4) {
|
|
61
|
+
return { mask, bounds: null };
|
|
62
|
+
}
|
|
63
|
+
for (let pixel = 0; pixel < pixelCount; pixel++) {
|
|
64
|
+
const rgbaIndex = pixel * 4;
|
|
65
|
+
const delta = Math.abs(annotated[rgbaIndex] - base[rgbaIndex]) + Math.abs(annotated[rgbaIndex + 1] - base[rgbaIndex + 1]) + Math.abs(annotated[rgbaIndex + 2] - base[rgbaIndex + 2]) + Math.abs(annotated[rgbaIndex + 3] - base[rgbaIndex + 3]);
|
|
66
|
+
const hasVisiblePixel = annotated[rgbaIndex + 3] > 0;
|
|
67
|
+
if (hasVisiblePixel && delta >= threshold) {
|
|
68
|
+
mask[pixel] = 1;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
return { mask, bounds: findMaskBounds(mask, width, height) };
|
|
72
|
+
}
|
|
73
|
+
export function applyMaskOrFallback(annotated, mask) {
|
|
74
|
+
const output = new Uint8ClampedArray(annotated);
|
|
75
|
+
const hasDiff = mask.includes(1);
|
|
76
|
+
if (!hasDiff) return { data: output, usedMask: false };
|
|
77
|
+
for (let pixel = 0; pixel < mask.length; pixel++) {
|
|
78
|
+
if (mask[pixel] === 1) continue;
|
|
79
|
+
const rgbaIndex = pixel * 4;
|
|
80
|
+
output[rgbaIndex] = 0;
|
|
81
|
+
output[rgbaIndex + 1] = 0;
|
|
82
|
+
output[rgbaIndex + 2] = 0;
|
|
83
|
+
output[rgbaIndex + 3] = 0;
|
|
84
|
+
}
|
|
85
|
+
return { data: output, usedMask: true };
|
|
86
|
+
}
|
|
87
|
+
function createCanvas(width, height) {
|
|
88
|
+
if (typeof document === "undefined") return null;
|
|
89
|
+
const canvas = document.createElement("canvas");
|
|
90
|
+
canvas.width = width;
|
|
91
|
+
canvas.height = height;
|
|
92
|
+
return canvas;
|
|
93
|
+
}
|
|
94
|
+
async function renderPageToCanvas(page, canvas, annotationMode, scale) {
|
|
95
|
+
const context = canvas.getContext("2d", { willReadFrequently: true });
|
|
96
|
+
if (!context) throw new Error("Unable to create canvas context for stamp extraction");
|
|
97
|
+
const viewport = page.getViewport({ scale });
|
|
98
|
+
const task = page.render({
|
|
99
|
+
canvasContext: context,
|
|
100
|
+
viewport,
|
|
101
|
+
annotationMode
|
|
102
|
+
});
|
|
103
|
+
await task.promise;
|
|
104
|
+
}
|
|
105
|
+
export async function extractStampAppearancesForPage(page, pageHeight, annotations, options = {}) {
|
|
106
|
+
const appearances = /* @__PURE__ */ new Map();
|
|
107
|
+
const stampAnnotations = annotations.filter(
|
|
108
|
+
(annotation) => annotation.annotationType === PdfjsAnnotationType.STAMP && typeof annotation.id === "string"
|
|
109
|
+
);
|
|
110
|
+
if (stampAnnotations.length === 0) return appearances;
|
|
111
|
+
const scale = options.scale ?? DEFAULT_RENDER_SCALE;
|
|
112
|
+
const diffThreshold = options.diffThreshold ?? DEFAULT_DIFF_THRESHOLD;
|
|
113
|
+
const viewport = page.getViewport({ scale });
|
|
114
|
+
const renderWidth = Math.max(1, Math.ceil(viewport.width));
|
|
115
|
+
const renderHeight = Math.max(1, Math.ceil(viewport.height));
|
|
116
|
+
const baseCanvas = createCanvas(renderWidth, renderHeight);
|
|
117
|
+
const annotatedCanvas = createCanvas(renderWidth, renderHeight);
|
|
118
|
+
if (!baseCanvas || !annotatedCanvas) return appearances;
|
|
119
|
+
try {
|
|
120
|
+
await renderPageToCanvas(page, baseCanvas, PDFJS_ANNOTATION_MODE_DISABLE, scale);
|
|
121
|
+
await renderPageToCanvas(page, annotatedCanvas, PDFJS_ANNOTATION_MODE_ENABLE, scale);
|
|
122
|
+
} catch (error) {
|
|
123
|
+
console.warn("[KViewer] Failed to render page for stamp extraction", error);
|
|
124
|
+
return appearances;
|
|
125
|
+
}
|
|
126
|
+
const baseContext = baseCanvas.getContext("2d", { willReadFrequently: true });
|
|
127
|
+
const annotatedContext = annotatedCanvas.getContext("2d", { willReadFrequently: true });
|
|
128
|
+
if (!baseContext || !annotatedContext) return appearances;
|
|
129
|
+
for (const annotation of stampAnnotations) {
|
|
130
|
+
try {
|
|
131
|
+
const id = annotation.id;
|
|
132
|
+
const bounds = stampRectToPixelBounds(
|
|
133
|
+
annotation.rect,
|
|
134
|
+
pageHeight,
|
|
135
|
+
scale,
|
|
136
|
+
renderWidth,
|
|
137
|
+
renderHeight
|
|
138
|
+
);
|
|
139
|
+
if (!bounds) continue;
|
|
140
|
+
const baseData = baseContext.getImageData(bounds.x, bounds.y, bounds.width, bounds.height);
|
|
141
|
+
const annotatedData = annotatedContext.getImageData(bounds.x, bounds.y, bounds.width, bounds.height);
|
|
142
|
+
const { mask } = computeDiffMask(
|
|
143
|
+
baseData.data,
|
|
144
|
+
annotatedData.data,
|
|
145
|
+
bounds.width,
|
|
146
|
+
bounds.height,
|
|
147
|
+
diffThreshold
|
|
148
|
+
);
|
|
149
|
+
const { data: maskedData } = applyMaskOrFallback(annotatedData.data, mask);
|
|
150
|
+
const outputCanvas = createCanvas(bounds.width, bounds.height);
|
|
151
|
+
if (!outputCanvas) continue;
|
|
152
|
+
const outputContext = outputCanvas.getContext("2d");
|
|
153
|
+
if (!outputContext) continue;
|
|
154
|
+
const outputImageData = outputContext.createImageData(bounds.width, bounds.height);
|
|
155
|
+
outputImageData.data.set(maskedData);
|
|
156
|
+
outputContext.putImageData(outputImageData, 0, 0);
|
|
157
|
+
const dataUrl = outputCanvas.toDataURL("image/png");
|
|
158
|
+
appearances.set(id, {
|
|
159
|
+
dataUrl,
|
|
160
|
+
width: bounds.width / scale,
|
|
161
|
+
height: bounds.height / scale
|
|
162
|
+
});
|
|
163
|
+
} catch (error) {
|
|
164
|
+
console.warn(`[KViewer] Failed to extract stamp appearance ${annotation.id}`, error);
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
return appearances;
|
|
168
|
+
}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
export interface RawPdfTextObject {
|
|
2
|
+
str?: unknown;
|
|
3
|
+
}
|
|
4
|
+
export interface RawPdfBorderStyle {
|
|
5
|
+
width?: unknown;
|
|
6
|
+
rawWidth?: unknown;
|
|
7
|
+
style?: unknown;
|
|
8
|
+
dashArray?: unknown;
|
|
9
|
+
}
|
|
10
|
+
export interface RawPdfPoint {
|
|
11
|
+
x?: unknown;
|
|
12
|
+
y?: unknown;
|
|
13
|
+
}
|
|
14
|
+
export interface RawPdfAppearanceData {
|
|
15
|
+
fontColor?: unknown;
|
|
16
|
+
fontSize?: unknown;
|
|
17
|
+
fontName?: unknown;
|
|
18
|
+
}
|
|
19
|
+
export interface RawPdfAnnotation {
|
|
20
|
+
id?: unknown;
|
|
21
|
+
annotationType?: unknown;
|
|
22
|
+
subtype?: unknown;
|
|
23
|
+
rect?: unknown;
|
|
24
|
+
color?: unknown;
|
|
25
|
+
borderStyle?: unknown;
|
|
26
|
+
titleObj?: unknown;
|
|
27
|
+
contentsObj?: unknown;
|
|
28
|
+
modificationDate?: unknown;
|
|
29
|
+
inReplyTo?: unknown;
|
|
30
|
+
quadPoints?: unknown;
|
|
31
|
+
defaultAppearanceData?: unknown;
|
|
32
|
+
inkLists?: unknown;
|
|
33
|
+
lineCoordinates?: unknown;
|
|
34
|
+
lineEndings?: unknown;
|
|
35
|
+
opacity?: unknown;
|
|
36
|
+
textPosition?: unknown;
|
|
37
|
+
textContent?: unknown;
|
|
38
|
+
}
|
|
39
|
+
export interface StampAppearance {
|
|
40
|
+
dataUrl: string;
|
|
41
|
+
width: number;
|
|
42
|
+
height: number;
|
|
43
|
+
}
|
|
44
|
+
export interface DecodeContext {
|
|
45
|
+
pageNumber: number;
|
|
46
|
+
pageHeight: number;
|
|
47
|
+
allAnnotations: RawPdfAnnotation[];
|
|
48
|
+
stampAppearances?: Map<string, StampAppearance>;
|
|
49
|
+
}
|
|
50
|
+
export declare function isRecord(value: unknown): value is Record<string, unknown>;
|
|
51
|
+
export declare function isString(value: unknown): value is string;
|
|
52
|
+
export declare function isNumber(value: unknown): value is number;
|
|
53
|
+
export declare function asBorderStyle(input: unknown): RawPdfBorderStyle | null;
|
|
54
|
+
export declare function asPoint(input: unknown): RawPdfPoint | null;
|
|
55
|
+
export declare function asTextObject(input: unknown): RawPdfTextObject | null;
|
|
56
|
+
export declare function asAppearanceData(input: unknown): RawPdfAppearanceData | null;
|
|
57
|
+
export declare function isRawPdfAnnotation(value: unknown): value is RawPdfAnnotation;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
export function isRecord(value) {
|
|
2
|
+
return !!value && typeof value === "object" && !Array.isArray(value);
|
|
3
|
+
}
|
|
4
|
+
export function isString(value) {
|
|
5
|
+
return typeof value === "string";
|
|
6
|
+
}
|
|
7
|
+
export function isNumber(value) {
|
|
8
|
+
return typeof value === "number" && Number.isFinite(value);
|
|
9
|
+
}
|
|
10
|
+
export function asBorderStyle(input) {
|
|
11
|
+
return isRecord(input) ? input : null;
|
|
12
|
+
}
|
|
13
|
+
export function asPoint(input) {
|
|
14
|
+
return isRecord(input) ? input : null;
|
|
15
|
+
}
|
|
16
|
+
export function asTextObject(input) {
|
|
17
|
+
return isRecord(input) ? input : null;
|
|
18
|
+
}
|
|
19
|
+
export function asAppearanceData(input) {
|
|
20
|
+
return isRecord(input) ? input : null;
|
|
21
|
+
}
|
|
22
|
+
export function isRawPdfAnnotation(value) {
|
|
23
|
+
if (!isRecord(value)) return false;
|
|
24
|
+
return isString(value.id) && isNumber(value.annotationType);
|
|
25
|
+
}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import Konva from 'konva';
|
|
2
|
+
import { type AnnotationType, type IAnnotationComment, type IAnnotationStore, type PdfjsAnnotationSubtype } from '../engine/types.js';
|
|
3
|
+
import { type RawPdfAnnotation } from './types.js';
|
|
4
|
+
type Rect = {
|
|
5
|
+
x: number;
|
|
6
|
+
y: number;
|
|
7
|
+
width: number;
|
|
8
|
+
height: number;
|
|
9
|
+
};
|
|
10
|
+
export interface StrokeWidthOptions {
|
|
11
|
+
preferRawWidth?: boolean;
|
|
12
|
+
}
|
|
13
|
+
export declare function colorArrayToRgb(input: unknown): string | null;
|
|
14
|
+
export declare function getAnnotationColor(annotation: RawPdfAnnotation, type: AnnotationType): string;
|
|
15
|
+
export declare function getAnnotationTitle(annotation: RawPdfAnnotation): string;
|
|
16
|
+
export declare function getAnnotationText(annotation: RawPdfAnnotation): string;
|
|
17
|
+
export declare function getFreeTextContent(annotation: RawPdfAnnotation): string;
|
|
18
|
+
export declare function getAnnotationDate(annotation: RawPdfAnnotation): string;
|
|
19
|
+
export declare function getComments(annotation: RawPdfAnnotation, allAnnotations: RawPdfAnnotation[]): IAnnotationComment[];
|
|
20
|
+
export declare function rectFromPdfRect(input: unknown, pageHeight: number): Rect | null;
|
|
21
|
+
export declare function pointFromPdfPoint(input: unknown, pageHeight: number): {
|
|
22
|
+
x: number;
|
|
23
|
+
y: number;
|
|
24
|
+
} | null;
|
|
25
|
+
export declare function localPointFromPdfPoint(input: unknown): {
|
|
26
|
+
x: number;
|
|
27
|
+
y: number;
|
|
28
|
+
} | null;
|
|
29
|
+
export declare function rectFromQuadPoints(input: unknown, pageHeight: number): Rect | null;
|
|
30
|
+
export declare function pointsFromInkList(input: unknown, pageHeight: number): number[];
|
|
31
|
+
export declare function linePointsFromCoordinates(input: unknown, pageHeight: number): number[] | null;
|
|
32
|
+
export declare function normalizedStrokeWidth(annotation: RawPdfAnnotation, fallback?: number, options?: StrokeWidthOptions): number;
|
|
33
|
+
export declare function dashedBorder(annotation: RawPdfAnnotation): number[];
|
|
34
|
+
export declare function hasArrowEnding(value: unknown): boolean;
|
|
35
|
+
export declare function createGhostGroup(id: string): Konva.Group;
|
|
36
|
+
export declare function createAnnotationStore(params: {
|
|
37
|
+
annotation: RawPdfAnnotation;
|
|
38
|
+
allAnnotations: RawPdfAnnotation[];
|
|
39
|
+
pageNumber: number;
|
|
40
|
+
type: AnnotationType;
|
|
41
|
+
group: Konva.Group;
|
|
42
|
+
color?: string;
|
|
43
|
+
fontSize?: number;
|
|
44
|
+
contentsText?: string;
|
|
45
|
+
contentsImage?: string;
|
|
46
|
+
overrideSubtype?: PdfjsAnnotationSubtype;
|
|
47
|
+
}): IAnnotationStore;
|
|
48
|
+
export {};
|