@embedpdf/plugin-annotation 3.0.0-next.10 → 3.0.0-next.12
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/authoring-BhtyfsMx.d.cts +37 -0
- package/dist/authoring-R4ezdnXd.d.ts +37 -0
- package/dist/authoring.cjs +16 -0
- package/dist/authoring.d.cts +2 -0
- package/dist/authoring.d.ts +2 -0
- package/dist/authoring.js +3 -0
- package/dist/{capability-BRf0HrOi.js → capability-Bh_1PL5v.js} +266 -280
- package/dist/capability-Bh_1PL5v.js.map +1 -0
- package/dist/{capability-Cl9x8oLS.cjs → capability-R7dgogJs.cjs} +332 -364
- package/dist/capability-R7dgogJs.cjs.map +1 -0
- package/dist/contract/host.cjs +3 -0
- package/dist/contract/host.d.cts +2 -0
- package/dist/contract/host.d.ts +2 -0
- package/dist/contract/host.js +2 -0
- package/dist/contract.cjs +10 -0
- package/dist/contract.cjs.map +1 -0
- package/dist/contract.d.cts +10 -0
- package/dist/contract.d.ts +10 -0
- package/dist/contract.js +8 -0
- package/dist/contract.js.map +1 -0
- package/dist/index.cjs +25 -24
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +5 -47
- package/dist/index.d.ts +5 -47
- package/dist/index.js +15 -15
- package/dist/index.js.map +1 -1
- package/dist/internal.cjs +4 -2
- package/dist/internal.d.cts +2 -1
- package/dist/internal.d.ts +2 -1
- package/dist/internal.js +3 -1
- package/dist/seam-6pJeKOOJ.cjs +296 -0
- package/dist/seam-6pJeKOOJ.cjs.map +1 -0
- package/dist/seam-C4L_7rDt.js +225 -0
- package/dist/seam-C4L_7rDt.js.map +1 -0
- package/dist/{types-Due7UgzE.d.cts → types-BAPdbfPT.d.cts} +89 -18
- package/dist/{types-DITX_3CG.d.ts → types-BgetZ4BK.d.ts} +88 -17
- package/dist/types-BvB1vUKb.js +20 -0
- package/dist/types-BvB1vUKb.js.map +1 -0
- package/dist/types-Dlhdw2k_.cjs +31 -0
- package/dist/types-Dlhdw2k_.cjs.map +1 -0
- package/package.json +21 -7
- package/dist/capability-BRf0HrOi.js.map +0 -1
- package/dist/capability-Cl9x8oLS.cjs.map +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"seam-6pJeKOOJ.cjs","names":[],"sources":["../src/repository/seam.ts"],"sourcesContent":["/**\n * The geometry/colour/rotation SEAM between the engine's PDF-space wire\n * vocabulary and the core's content-space model. Every conversion between the\n * two worlds lives here — kind modules speak through these helpers and never\n * hand-roll a convention flip.\n */\nimport type {\n AnnotationDTO,\n AnnotationRef,\n Color,\n PdfLinkTarget,\n PdfLinkTargetWritable,\n PdfRect,\n PdfRectDifferences,\n StandardFont,\n WidgetAppearance,\n} from '@embedpdf/engine-core/runtime';\nimport {\n contentToPdfRect,\n normalizeDeg,\n pdfToContentRect,\n rotatedAabb,\n type AnnotationPropsPatch,\n type Border,\n type Geom,\n type Rect,\n type Style,\n} from '@embedpdf/core-annotation';\n\n// The content↔PDF bridge, re-exported so kind modules cross the seam through\n// ONE import point and never reach into the core's geometry directly.\nexport {\n contentToPdfPoint,\n contentToPdfRect,\n pdfToContentPoint,\n pdfToContentRect,\n} from '@embedpdf/core-annotation';\n\nexport function refKey(ref: AnnotationRef): string {\n return ref.kind === 'objectNumber'\n ? `obj:${ref.annotObjectNumber}`\n : ref.kind === 'nm'\n ? `nm:${ref.nm}`\n : `idx:${ref.pageObjectNumber}:${ref.index}`;\n}\n\n/* ── colour seam (engine Color ↔ CSS hex) ─────────────────────────────────── */\n\nconst h2 = (n: number) =>\n Math.max(0, Math.min(255, Math.round(n)))\n .toString(16)\n .padStart(2, '0');\nexport const colorToCss = (c: Color): string => `#${h2(c.r)}${h2(c.g)}${h2(c.b)}`;\nexport function cssToColor(css: string): Color {\n const s = css.trim();\n const m6 = /^#?([0-9a-f]{6})$/i.exec(s);\n if (m6) {\n const n = parseInt(m6[1], 16);\n return { r: (n >> 16) & 255, g: (n >> 8) & 255, b: n & 255 };\n }\n const m3 = /^#?([0-9a-f]{3})$/i.exec(s);\n if (m3) {\n const [a, b, c] = m3[1];\n return { r: parseInt(a + a, 16), g: parseInt(b + b, 16), b: parseInt(c + c, 16) };\n }\n return { r: 0, g: 0, b: 0 };\n}\n\n/* ── rotation seam (CW content ↔ PDF convention) ──────────────────────────────\n * The model's `rot` is CLOCKWISE in content space (y-down). PDF user space is\n * y-up, so the y-flip at this boundary turns a CW content tilt into a CCW PDF\n * tilt of the same magnitude — i.e. the stored `/EMBD_Metadata/Rotation` is the\n * NEGATION (mod 360). This is the ONE place the convention is converted; every\n * layer above speaks CW-content and the engine/PDFium speaks the PDF angle.\n */\nexport const toPdfRotation = (rotCW: number): number => normalizeDeg(-rotCW);\nexport const fromPdfRotation = (rotPdf: number): number => normalizeDeg(-rotPdf);\n\n/** Advisory `rot` for a vertex geom, from a DTO's (PDF-convention) `rotation`.\n * Absent → no `rot` key (kept off the geom so unrotated shapes stay clean). */\nexport const rotFromDTO = (rotation?: number): { rot?: number } =>\n rotation ? { rot: fromPdfRotation(rotation) } : {};\n\n/**\n * Geometry/rotation fields for a BOX kind (square/circle/plain free-text). The\n * model's `rect` is the UNROTATED logical box and `rot` the applied tilt, so:\n * - rot == 0 → `/Rect` IS the box; the transform pair is stated as `null`\n * (TOTAL projection — the engine's tri-state writes preserve omissions, so\n * an omitted field would keep a stale rotation instead of flattening it).\n * - rot != 0 → `/Rect` is the rotated visual AABB (PDFium clips the baked /AP\n * to it), `unrotatedRect` the logical box, `rotation` the PDF angle.\n */\nexport function boxGeomFields(\n rect: Rect,\n rot: number,\n crop: PdfRect,\n): { rect: PdfRect; unrotatedRect: PdfRect | null; rotation: number | null } {\n if (!rot) return { rect: contentToPdfRect(rect, crop), rotation: null, unrotatedRect: null };\n return {\n rect: contentToPdfRect(rotatedAabb(rect, rot), crop),\n unrotatedRect: contentToPdfRect(rect, crop),\n rotation: toPdfRotation(rot),\n };\n}\n\n/** A box geom (square/circle/stamp) from its DTO: when rotated, the LOCAL box\n * is the stored `unrotatedRect` (the AABB `/Rect` is the rendered envelope)\n * and `rot` the converted tilt; unrotated, `/Rect` IS the box. */\nexport function boxGeomFromDTO(\n dto: { rect: PdfRect },\n rotation: number | undefined,\n unrotatedRect: PdfRect | undefined,\n crop: PdfRect,\n ellipse: boolean,\n): Geom {\n const rot = rotation ? fromPdfRotation(rotation) : 0;\n const box = rot && unrotatedRect ? unrotatedRect : dto.rect;\n return { t: 'rect', rect: pdfToContentRect(box, crop), ellipse, ...(rot ? { rot } : {}) };\n}\n\n/** Inset a PdfRect by a `/RD` (PDF user space, y-up: all four are non-negative\n * insets from the matching `/Rect` edge). Used to recover the callout text box. */\nexport const insetPdfRectByRD = (r: PdfRect, rd?: PdfRectDifferences | null): PdfRect =>\n rd\n ? {\n left: r.left + rd.left,\n bottom: r.bottom + rd.bottom,\n right: r.right - rd.right,\n top: r.top - rd.top,\n }\n : r;\n\n/** Engine border fields (`/BS /S`, `/BS /D`, `/BE /I`) → the `Border` union. A\n * cloudy effect wins over the underlying border style (which stays solid). */\nexport function borderFromDTO(d: {\n borderStyle?: string;\n dashArray?: number[];\n cloudyIntensity?: number | null;\n}): Border {\n if ((d.cloudyIntensity ?? 0) > 0) return { kind: 'cloudy', intensity: d.cloudyIntensity! };\n if (d.borderStyle === 'dashed')\n return { kind: 'dashed', dash: d.dashArray?.length ? d.dashArray : [3, 3] };\n return { kind: 'solid' };\n}\n\n/** The writable projection of a `link` value: `goto`/`uri` pass through,\n * read-only arms (`javascript`, `named`, `goto-remote`, `launch`,\n * `unsupported`) yield `null` — they can be carried, never (re)written. */\nexport function writableTarget(t: PdfLinkTarget | null | undefined): PdfLinkTargetWritable | null {\n return t && (t.kind === 'goto' || t.kind === 'uri') ? t : null;\n}\n\nexport const TEXT_MARKUP = new Set(['highlight', 'underline', 'squiggly', 'strikeout']);\n// Geometric kinds that carry the `/C` stroke colour + `/BS` border. Ink belongs\n// here too (it has a stroke but no `/IC`, so its interiorColor reads back null).\nconst STROKE_KINDS = new Set(['square', 'circle', 'line', 'polygon', 'polyline', 'ink']);\n\n/** Engine DTO → content-space `Style` (CSS colours, `Border` union). Exported so\n * selection-aware UIs can read display values straight off a {@link AnnotationDTO}\n * without re-deriving the colour/border mapping. */\nexport function styleFromDTO(dto: AnnotationDTO): Style {\n if (dto.subtype === 'widget') {\n return {\n color: dto.color ? colorToCss(dto.color) : '#1a1a1a',\n interiorColor: dto.interiorColor ? colorToCss(dto.interiorColor) : null,\n strokeWidth: dto.strokeWidth,\n opacity: 1,\n blendMode: dto.blendMode,\n border: dto.borderStyle === 'dashed' ? { kind: 'dashed', dash: [3, 3] } : { kind: 'solid' },\n };\n }\n if (STROKE_KINDS.has(dto.subtype)) {\n const d = dto as Extract<\n AnnotationDTO,\n { interiorColor: Color | null; opacity: number; strokeWidth: number }\n >;\n return {\n color: colorToCss(d.color),\n interiorColor: d.interiorColor ? colorToCss(d.interiorColor) : null,\n strokeWidth: d.strokeWidth,\n opacity: d.opacity,\n blendMode: dto.blendMode,\n border: borderFromDTO(d),\n };\n }\n if (TEXT_MARKUP.has(dto.subtype)) {\n const d = dto as Extract<AnnotationDTO, { color: Color }>;\n return {\n color: colorToCss(d.color),\n interiorColor: null,\n strokeWidth: 0,\n opacity: d.opacity,\n blendMode: dto.blendMode,\n border: { kind: 'solid' },\n };\n }\n if (dto.subtype === 'caret') {\n const d = dto as Extract<AnnotationDTO, { color: Color; opacity: number }>;\n return {\n color: colorToCss(d.color),\n interiorColor: null,\n strokeWidth: 1,\n opacity: d.opacity,\n blendMode: dto.blendMode,\n border: { kind: 'solid' },\n };\n }\n if (dto.subtype === 'free-text') {\n // `/DA` colour is the border + leader stroke; `/C` is the box background; `/BS`\n // gives the width. A plain text box draws no vector scene, so these only matter\n // for a callout's leader/arrow/box-border (and the style toolbar's readout).\n const d = dto as Extract<AnnotationDTO, { subtype: 'free-text' }>;\n return {\n color: colorToCss(d.color),\n interiorColor: d.interiorColor ? colorToCss(d.interiorColor) : null,\n strokeWidth: d.strokeWidth,\n opacity: d.opacity,\n blendMode: dto.blendMode,\n border: borderFromDTO(d),\n };\n }\n if (dto.subtype === 'redact') {\n // `/C` is the marking-stage outline; `/IC` the fill painted on apply.\n // No `/BS` on redact — the outline weight is a client rendering choice.\n const d = dto as Extract<AnnotationDTO, { subtype: 'redact' }>;\n return {\n color: colorToCss(d.color),\n interiorColor: d.interiorColor ? colorToCss(d.interiorColor) : null,\n strokeWidth: 1.5,\n opacity: d.opacity,\n blendMode: dto.blendMode,\n border: { kind: 'solid' },\n };\n }\n if (dto.subtype === 'text' || dto.subtype === 'file-attachment') {\n // Icon kinds: /C is the icon fill, /CA its opacity — no stroke/fill split.\n const d = dto as Extract<AnnotationDTO, { color: Color; opacity: number }>;\n return {\n color: colorToCss(d.color),\n interiorColor: null,\n strokeWidth: 1,\n opacity: d.opacity,\n blendMode: dto.blendMode,\n border: { kind: 'solid' },\n };\n }\n return {\n color: '#444444',\n interiorColor: null,\n strokeWidth: 1,\n opacity: 1,\n blendMode: dto.blendMode,\n border: { kind: 'solid' },\n };\n}\n\n/**\n * The flat props vocabulary (CSS colours, house keys) → the engine's widget\n * appearance for `doc.forms` authoring — the SAME mapping the widget patch\n * lowering uses, exported as a boundary utility so the form plugin can style\n * `placeField` from a tool's `currentDefaults` without growing a second CSS\n * parser. Absent keys stay absent (the engine writes nothing for them).\n */\nexport function widgetAppearanceFromProps(props: AnnotationPropsPatch): WidgetAppearance {\n return {\n ...(props.color !== undefined ? { color: cssToColor(props.color) } : {}),\n ...(props.interiorColor !== undefined\n ? { interiorColor: props.interiorColor ? cssToColor(props.interiorColor) : null }\n : {}),\n ...(props.strokeWidth !== undefined ? { strokeWidth: props.strokeWidth } : {}),\n ...(props.border !== undefined\n ? { borderStyle: props.border.kind === 'dashed' ? ('dashed' as const) : ('solid' as const) }\n : {}),\n ...(props.fontFamily !== undefined ? { fontFamily: props.fontFamily as StandardFont } : {}),\n ...(props.fontSize !== undefined ? { fontSize: props.fontSize } : {}),\n ...(props.fontColor !== undefined ? { fontColor: cssToColor(props.fontColor) } : {}),\n ...(props.textAlign !== undefined ? { textAlign: props.textAlign } : {}),\n };\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,225 @@
|
|
|
1
|
+
import { contentToPdfPoint, contentToPdfRect, contentToPdfRect as contentToPdfRect$1, normalizeDeg, pdfToContentPoint as pdfToContentPoint$1, pdfToContentRect, pdfToContentRect as pdfToContentRect$1, rotatedAabb } from "@embedpdf/core-annotation";
|
|
2
|
+
//#region src/repository/seam.ts
|
|
3
|
+
function refKey(ref) {
|
|
4
|
+
return ref.kind === "objectNumber" ? `obj:${ref.annotObjectNumber}` : ref.kind === "nm" ? `nm:${ref.nm}` : `idx:${ref.pageObjectNumber}:${ref.index}`;
|
|
5
|
+
}
|
|
6
|
+
const h2 = (n) => Math.max(0, Math.min(255, Math.round(n))).toString(16).padStart(2, "0");
|
|
7
|
+
const colorToCss = (c) => `#${h2(c.r)}${h2(c.g)}${h2(c.b)}`;
|
|
8
|
+
function cssToColor(css) {
|
|
9
|
+
const s = css.trim();
|
|
10
|
+
const m6 = /^#?([0-9a-f]{6})$/i.exec(s);
|
|
11
|
+
if (m6) {
|
|
12
|
+
const n = parseInt(m6[1], 16);
|
|
13
|
+
return {
|
|
14
|
+
r: n >> 16 & 255,
|
|
15
|
+
g: n >> 8 & 255,
|
|
16
|
+
b: n & 255
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
const m3 = /^#?([0-9a-f]{3})$/i.exec(s);
|
|
20
|
+
if (m3) {
|
|
21
|
+
const [a, b, c] = m3[1];
|
|
22
|
+
return {
|
|
23
|
+
r: parseInt(a + a, 16),
|
|
24
|
+
g: parseInt(b + b, 16),
|
|
25
|
+
b: parseInt(c + c, 16)
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
return {
|
|
29
|
+
r: 0,
|
|
30
|
+
g: 0,
|
|
31
|
+
b: 0
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
const toPdfRotation = (rotCW) => normalizeDeg(-rotCW);
|
|
35
|
+
const fromPdfRotation = (rotPdf) => normalizeDeg(-rotPdf);
|
|
36
|
+
/** Advisory `rot` for a vertex geom, from a DTO's (PDF-convention) `rotation`.
|
|
37
|
+
* Absent → no `rot` key (kept off the geom so unrotated shapes stay clean). */
|
|
38
|
+
const rotFromDTO = (rotation) => rotation ? { rot: fromPdfRotation(rotation) } : {};
|
|
39
|
+
/**
|
|
40
|
+
* Geometry/rotation fields for a BOX kind (square/circle/plain free-text). The
|
|
41
|
+
* model's `rect` is the UNROTATED logical box and `rot` the applied tilt, so:
|
|
42
|
+
* - rot == 0 → `/Rect` IS the box; the transform pair is stated as `null`
|
|
43
|
+
* (TOTAL projection — the engine's tri-state writes preserve omissions, so
|
|
44
|
+
* an omitted field would keep a stale rotation instead of flattening it).
|
|
45
|
+
* - rot != 0 → `/Rect` is the rotated visual AABB (PDFium clips the baked /AP
|
|
46
|
+
* to it), `unrotatedRect` the logical box, `rotation` the PDF angle.
|
|
47
|
+
*/
|
|
48
|
+
function boxGeomFields(rect, rot, crop) {
|
|
49
|
+
if (!rot) return {
|
|
50
|
+
rect: contentToPdfRect(rect, crop),
|
|
51
|
+
rotation: null,
|
|
52
|
+
unrotatedRect: null
|
|
53
|
+
};
|
|
54
|
+
return {
|
|
55
|
+
rect: contentToPdfRect(rotatedAabb(rect, rot), crop),
|
|
56
|
+
unrotatedRect: contentToPdfRect(rect, crop),
|
|
57
|
+
rotation: toPdfRotation(rot)
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
/** A box geom (square/circle/stamp) from its DTO: when rotated, the LOCAL box
|
|
61
|
+
* is the stored `unrotatedRect` (the AABB `/Rect` is the rendered envelope)
|
|
62
|
+
* and `rot` the converted tilt; unrotated, `/Rect` IS the box. */
|
|
63
|
+
function boxGeomFromDTO(dto, rotation, unrotatedRect, crop, ellipse) {
|
|
64
|
+
const rot = rotation ? fromPdfRotation(rotation) : 0;
|
|
65
|
+
return {
|
|
66
|
+
t: "rect",
|
|
67
|
+
rect: pdfToContentRect(rot && unrotatedRect ? unrotatedRect : dto.rect, crop),
|
|
68
|
+
ellipse,
|
|
69
|
+
...rot ? { rot } : {}
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
/** Inset a PdfRect by a `/RD` (PDF user space, y-up: all four are non-negative
|
|
73
|
+
* insets from the matching `/Rect` edge). Used to recover the callout text box. */
|
|
74
|
+
const insetPdfRectByRD = (r, rd) => rd ? {
|
|
75
|
+
left: r.left + rd.left,
|
|
76
|
+
bottom: r.bottom + rd.bottom,
|
|
77
|
+
right: r.right - rd.right,
|
|
78
|
+
top: r.top - rd.top
|
|
79
|
+
} : r;
|
|
80
|
+
/** Engine border fields (`/BS /S`, `/BS /D`, `/BE /I`) → the `Border` union. A
|
|
81
|
+
* cloudy effect wins over the underlying border style (which stays solid). */
|
|
82
|
+
function borderFromDTO(d) {
|
|
83
|
+
if ((d.cloudyIntensity ?? 0) > 0) return {
|
|
84
|
+
kind: "cloudy",
|
|
85
|
+
intensity: d.cloudyIntensity
|
|
86
|
+
};
|
|
87
|
+
if (d.borderStyle === "dashed") return {
|
|
88
|
+
kind: "dashed",
|
|
89
|
+
dash: d.dashArray?.length ? d.dashArray : [3, 3]
|
|
90
|
+
};
|
|
91
|
+
return { kind: "solid" };
|
|
92
|
+
}
|
|
93
|
+
/** The writable projection of a `link` value: `goto`/`uri` pass through,
|
|
94
|
+
* read-only arms (`javascript`, `named`, `goto-remote`, `launch`,
|
|
95
|
+
* `unsupported`) yield `null` — they can be carried, never (re)written. */
|
|
96
|
+
function writableTarget(t) {
|
|
97
|
+
return t && (t.kind === "goto" || t.kind === "uri") ? t : null;
|
|
98
|
+
}
|
|
99
|
+
const TEXT_MARKUP = /* @__PURE__ */ new Set([
|
|
100
|
+
"highlight",
|
|
101
|
+
"underline",
|
|
102
|
+
"squiggly",
|
|
103
|
+
"strikeout"
|
|
104
|
+
]);
|
|
105
|
+
const STROKE_KINDS = /* @__PURE__ */ new Set([
|
|
106
|
+
"square",
|
|
107
|
+
"circle",
|
|
108
|
+
"line",
|
|
109
|
+
"polygon",
|
|
110
|
+
"polyline",
|
|
111
|
+
"ink"
|
|
112
|
+
]);
|
|
113
|
+
/** Engine DTO → content-space `Style` (CSS colours, `Border` union). Exported so
|
|
114
|
+
* selection-aware UIs can read display values straight off a {@link AnnotationDTO}
|
|
115
|
+
* without re-deriving the colour/border mapping. */
|
|
116
|
+
function styleFromDTO(dto) {
|
|
117
|
+
if (dto.subtype === "widget") return {
|
|
118
|
+
color: dto.color ? colorToCss(dto.color) : "#1a1a1a",
|
|
119
|
+
interiorColor: dto.interiorColor ? colorToCss(dto.interiorColor) : null,
|
|
120
|
+
strokeWidth: dto.strokeWidth,
|
|
121
|
+
opacity: 1,
|
|
122
|
+
blendMode: dto.blendMode,
|
|
123
|
+
border: dto.borderStyle === "dashed" ? {
|
|
124
|
+
kind: "dashed",
|
|
125
|
+
dash: [3, 3]
|
|
126
|
+
} : { kind: "solid" }
|
|
127
|
+
};
|
|
128
|
+
if (STROKE_KINDS.has(dto.subtype)) {
|
|
129
|
+
const d = dto;
|
|
130
|
+
return {
|
|
131
|
+
color: colorToCss(d.color),
|
|
132
|
+
interiorColor: d.interiorColor ? colorToCss(d.interiorColor) : null,
|
|
133
|
+
strokeWidth: d.strokeWidth,
|
|
134
|
+
opacity: d.opacity,
|
|
135
|
+
blendMode: dto.blendMode,
|
|
136
|
+
border: borderFromDTO(d)
|
|
137
|
+
};
|
|
138
|
+
}
|
|
139
|
+
if (TEXT_MARKUP.has(dto.subtype)) {
|
|
140
|
+
const d = dto;
|
|
141
|
+
return {
|
|
142
|
+
color: colorToCss(d.color),
|
|
143
|
+
interiorColor: null,
|
|
144
|
+
strokeWidth: 0,
|
|
145
|
+
opacity: d.opacity,
|
|
146
|
+
blendMode: dto.blendMode,
|
|
147
|
+
border: { kind: "solid" }
|
|
148
|
+
};
|
|
149
|
+
}
|
|
150
|
+
if (dto.subtype === "caret") {
|
|
151
|
+
const d = dto;
|
|
152
|
+
return {
|
|
153
|
+
color: colorToCss(d.color),
|
|
154
|
+
interiorColor: null,
|
|
155
|
+
strokeWidth: 1,
|
|
156
|
+
opacity: d.opacity,
|
|
157
|
+
blendMode: dto.blendMode,
|
|
158
|
+
border: { kind: "solid" }
|
|
159
|
+
};
|
|
160
|
+
}
|
|
161
|
+
if (dto.subtype === "free-text") {
|
|
162
|
+
const d = dto;
|
|
163
|
+
return {
|
|
164
|
+
color: colorToCss(d.color),
|
|
165
|
+
interiorColor: d.interiorColor ? colorToCss(d.interiorColor) : null,
|
|
166
|
+
strokeWidth: d.strokeWidth,
|
|
167
|
+
opacity: d.opacity,
|
|
168
|
+
blendMode: dto.blendMode,
|
|
169
|
+
border: borderFromDTO(d)
|
|
170
|
+
};
|
|
171
|
+
}
|
|
172
|
+
if (dto.subtype === "redact") {
|
|
173
|
+
const d = dto;
|
|
174
|
+
return {
|
|
175
|
+
color: colorToCss(d.color),
|
|
176
|
+
interiorColor: d.interiorColor ? colorToCss(d.interiorColor) : null,
|
|
177
|
+
strokeWidth: 1.5,
|
|
178
|
+
opacity: d.opacity,
|
|
179
|
+
blendMode: dto.blendMode,
|
|
180
|
+
border: { kind: "solid" }
|
|
181
|
+
};
|
|
182
|
+
}
|
|
183
|
+
if (dto.subtype === "text" || dto.subtype === "file-attachment") {
|
|
184
|
+
const d = dto;
|
|
185
|
+
return {
|
|
186
|
+
color: colorToCss(d.color),
|
|
187
|
+
interiorColor: null,
|
|
188
|
+
strokeWidth: 1,
|
|
189
|
+
opacity: d.opacity,
|
|
190
|
+
blendMode: dto.blendMode,
|
|
191
|
+
border: { kind: "solid" }
|
|
192
|
+
};
|
|
193
|
+
}
|
|
194
|
+
return {
|
|
195
|
+
color: "#444444",
|
|
196
|
+
interiorColor: null,
|
|
197
|
+
strokeWidth: 1,
|
|
198
|
+
opacity: 1,
|
|
199
|
+
blendMode: dto.blendMode,
|
|
200
|
+
border: { kind: "solid" }
|
|
201
|
+
};
|
|
202
|
+
}
|
|
203
|
+
/**
|
|
204
|
+
* The flat props vocabulary (CSS colours, house keys) → the engine's widget
|
|
205
|
+
* appearance for `doc.forms` authoring — the SAME mapping the widget patch
|
|
206
|
+
* lowering uses, exported as a boundary utility so the form plugin can style
|
|
207
|
+
* `placeField` from a tool's `currentDefaults` without growing a second CSS
|
|
208
|
+
* parser. Absent keys stay absent (the engine writes nothing for them).
|
|
209
|
+
*/
|
|
210
|
+
function widgetAppearanceFromProps(props) {
|
|
211
|
+
return {
|
|
212
|
+
...props.color !== void 0 ? { color: cssToColor(props.color) } : {},
|
|
213
|
+
...props.interiorColor !== void 0 ? { interiorColor: props.interiorColor ? cssToColor(props.interiorColor) : null } : {},
|
|
214
|
+
...props.strokeWidth !== void 0 ? { strokeWidth: props.strokeWidth } : {},
|
|
215
|
+
...props.border !== void 0 ? { borderStyle: props.border.kind === "dashed" ? "dashed" : "solid" } : {},
|
|
216
|
+
...props.fontFamily !== void 0 ? { fontFamily: props.fontFamily } : {},
|
|
217
|
+
...props.fontSize !== void 0 ? { fontSize: props.fontSize } : {},
|
|
218
|
+
...props.fontColor !== void 0 ? { fontColor: cssToColor(props.fontColor) } : {},
|
|
219
|
+
...props.textAlign !== void 0 ? { textAlign: props.textAlign } : {}
|
|
220
|
+
};
|
|
221
|
+
}
|
|
222
|
+
//#endregion
|
|
223
|
+
export { contentToPdfRect$1 as a, insetPdfRectByRD as c, refKey as d, rotFromDTO as f, writableTarget as g, widgetAppearanceFromProps as h, contentToPdfPoint as i, pdfToContentPoint$1 as l, toPdfRotation as m, boxGeomFromDTO as n, cssToColor as o, styleFromDTO as p, colorToCss as r, fromPdfRotation as s, boxGeomFields as t, pdfToContentRect$1 as u };
|
|
224
|
+
|
|
225
|
+
//# sourceMappingURL=seam-C4L_7rDt.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"seam-C4L_7rDt.js","names":[],"sources":["../src/repository/seam.ts"],"sourcesContent":["/**\n * The geometry/colour/rotation SEAM between the engine's PDF-space wire\n * vocabulary and the core's content-space model. Every conversion between the\n * two worlds lives here — kind modules speak through these helpers and never\n * hand-roll a convention flip.\n */\nimport type {\n AnnotationDTO,\n AnnotationRef,\n Color,\n PdfLinkTarget,\n PdfLinkTargetWritable,\n PdfRect,\n PdfRectDifferences,\n StandardFont,\n WidgetAppearance,\n} from '@embedpdf/engine-core/runtime';\nimport {\n contentToPdfRect,\n normalizeDeg,\n pdfToContentRect,\n rotatedAabb,\n type AnnotationPropsPatch,\n type Border,\n type Geom,\n type Rect,\n type Style,\n} from '@embedpdf/core-annotation';\n\n// The content↔PDF bridge, re-exported so kind modules cross the seam through\n// ONE import point and never reach into the core's geometry directly.\nexport {\n contentToPdfPoint,\n contentToPdfRect,\n pdfToContentPoint,\n pdfToContentRect,\n} from '@embedpdf/core-annotation';\n\nexport function refKey(ref: AnnotationRef): string {\n return ref.kind === 'objectNumber'\n ? `obj:${ref.annotObjectNumber}`\n : ref.kind === 'nm'\n ? `nm:${ref.nm}`\n : `idx:${ref.pageObjectNumber}:${ref.index}`;\n}\n\n/* ── colour seam (engine Color ↔ CSS hex) ─────────────────────────────────── */\n\nconst h2 = (n: number) =>\n Math.max(0, Math.min(255, Math.round(n)))\n .toString(16)\n .padStart(2, '0');\nexport const colorToCss = (c: Color): string => `#${h2(c.r)}${h2(c.g)}${h2(c.b)}`;\nexport function cssToColor(css: string): Color {\n const s = css.trim();\n const m6 = /^#?([0-9a-f]{6})$/i.exec(s);\n if (m6) {\n const n = parseInt(m6[1], 16);\n return { r: (n >> 16) & 255, g: (n >> 8) & 255, b: n & 255 };\n }\n const m3 = /^#?([0-9a-f]{3})$/i.exec(s);\n if (m3) {\n const [a, b, c] = m3[1];\n return { r: parseInt(a + a, 16), g: parseInt(b + b, 16), b: parseInt(c + c, 16) };\n }\n return { r: 0, g: 0, b: 0 };\n}\n\n/* ── rotation seam (CW content ↔ PDF convention) ──────────────────────────────\n * The model's `rot` is CLOCKWISE in content space (y-down). PDF user space is\n * y-up, so the y-flip at this boundary turns a CW content tilt into a CCW PDF\n * tilt of the same magnitude — i.e. the stored `/EMBD_Metadata/Rotation` is the\n * NEGATION (mod 360). This is the ONE place the convention is converted; every\n * layer above speaks CW-content and the engine/PDFium speaks the PDF angle.\n */\nexport const toPdfRotation = (rotCW: number): number => normalizeDeg(-rotCW);\nexport const fromPdfRotation = (rotPdf: number): number => normalizeDeg(-rotPdf);\n\n/** Advisory `rot` for a vertex geom, from a DTO's (PDF-convention) `rotation`.\n * Absent → no `rot` key (kept off the geom so unrotated shapes stay clean). */\nexport const rotFromDTO = (rotation?: number): { rot?: number } =>\n rotation ? { rot: fromPdfRotation(rotation) } : {};\n\n/**\n * Geometry/rotation fields for a BOX kind (square/circle/plain free-text). The\n * model's `rect` is the UNROTATED logical box and `rot` the applied tilt, so:\n * - rot == 0 → `/Rect` IS the box; the transform pair is stated as `null`\n * (TOTAL projection — the engine's tri-state writes preserve omissions, so\n * an omitted field would keep a stale rotation instead of flattening it).\n * - rot != 0 → `/Rect` is the rotated visual AABB (PDFium clips the baked /AP\n * to it), `unrotatedRect` the logical box, `rotation` the PDF angle.\n */\nexport function boxGeomFields(\n rect: Rect,\n rot: number,\n crop: PdfRect,\n): { rect: PdfRect; unrotatedRect: PdfRect | null; rotation: number | null } {\n if (!rot) return { rect: contentToPdfRect(rect, crop), rotation: null, unrotatedRect: null };\n return {\n rect: contentToPdfRect(rotatedAabb(rect, rot), crop),\n unrotatedRect: contentToPdfRect(rect, crop),\n rotation: toPdfRotation(rot),\n };\n}\n\n/** A box geom (square/circle/stamp) from its DTO: when rotated, the LOCAL box\n * is the stored `unrotatedRect` (the AABB `/Rect` is the rendered envelope)\n * and `rot` the converted tilt; unrotated, `/Rect` IS the box. */\nexport function boxGeomFromDTO(\n dto: { rect: PdfRect },\n rotation: number | undefined,\n unrotatedRect: PdfRect | undefined,\n crop: PdfRect,\n ellipse: boolean,\n): Geom {\n const rot = rotation ? fromPdfRotation(rotation) : 0;\n const box = rot && unrotatedRect ? unrotatedRect : dto.rect;\n return { t: 'rect', rect: pdfToContentRect(box, crop), ellipse, ...(rot ? { rot } : {}) };\n}\n\n/** Inset a PdfRect by a `/RD` (PDF user space, y-up: all four are non-negative\n * insets from the matching `/Rect` edge). Used to recover the callout text box. */\nexport const insetPdfRectByRD = (r: PdfRect, rd?: PdfRectDifferences | null): PdfRect =>\n rd\n ? {\n left: r.left + rd.left,\n bottom: r.bottom + rd.bottom,\n right: r.right - rd.right,\n top: r.top - rd.top,\n }\n : r;\n\n/** Engine border fields (`/BS /S`, `/BS /D`, `/BE /I`) → the `Border` union. A\n * cloudy effect wins over the underlying border style (which stays solid). */\nexport function borderFromDTO(d: {\n borderStyle?: string;\n dashArray?: number[];\n cloudyIntensity?: number | null;\n}): Border {\n if ((d.cloudyIntensity ?? 0) > 0) return { kind: 'cloudy', intensity: d.cloudyIntensity! };\n if (d.borderStyle === 'dashed')\n return { kind: 'dashed', dash: d.dashArray?.length ? d.dashArray : [3, 3] };\n return { kind: 'solid' };\n}\n\n/** The writable projection of a `link` value: `goto`/`uri` pass through,\n * read-only arms (`javascript`, `named`, `goto-remote`, `launch`,\n * `unsupported`) yield `null` — they can be carried, never (re)written. */\nexport function writableTarget(t: PdfLinkTarget | null | undefined): PdfLinkTargetWritable | null {\n return t && (t.kind === 'goto' || t.kind === 'uri') ? t : null;\n}\n\nexport const TEXT_MARKUP = new Set(['highlight', 'underline', 'squiggly', 'strikeout']);\n// Geometric kinds that carry the `/C` stroke colour + `/BS` border. Ink belongs\n// here too (it has a stroke but no `/IC`, so its interiorColor reads back null).\nconst STROKE_KINDS = new Set(['square', 'circle', 'line', 'polygon', 'polyline', 'ink']);\n\n/** Engine DTO → content-space `Style` (CSS colours, `Border` union). Exported so\n * selection-aware UIs can read display values straight off a {@link AnnotationDTO}\n * without re-deriving the colour/border mapping. */\nexport function styleFromDTO(dto: AnnotationDTO): Style {\n if (dto.subtype === 'widget') {\n return {\n color: dto.color ? colorToCss(dto.color) : '#1a1a1a',\n interiorColor: dto.interiorColor ? colorToCss(dto.interiorColor) : null,\n strokeWidth: dto.strokeWidth,\n opacity: 1,\n blendMode: dto.blendMode,\n border: dto.borderStyle === 'dashed' ? { kind: 'dashed', dash: [3, 3] } : { kind: 'solid' },\n };\n }\n if (STROKE_KINDS.has(dto.subtype)) {\n const d = dto as Extract<\n AnnotationDTO,\n { interiorColor: Color | null; opacity: number; strokeWidth: number }\n >;\n return {\n color: colorToCss(d.color),\n interiorColor: d.interiorColor ? colorToCss(d.interiorColor) : null,\n strokeWidth: d.strokeWidth,\n opacity: d.opacity,\n blendMode: dto.blendMode,\n border: borderFromDTO(d),\n };\n }\n if (TEXT_MARKUP.has(dto.subtype)) {\n const d = dto as Extract<AnnotationDTO, { color: Color }>;\n return {\n color: colorToCss(d.color),\n interiorColor: null,\n strokeWidth: 0,\n opacity: d.opacity,\n blendMode: dto.blendMode,\n border: { kind: 'solid' },\n };\n }\n if (dto.subtype === 'caret') {\n const d = dto as Extract<AnnotationDTO, { color: Color; opacity: number }>;\n return {\n color: colorToCss(d.color),\n interiorColor: null,\n strokeWidth: 1,\n opacity: d.opacity,\n blendMode: dto.blendMode,\n border: { kind: 'solid' },\n };\n }\n if (dto.subtype === 'free-text') {\n // `/DA` colour is the border + leader stroke; `/C` is the box background; `/BS`\n // gives the width. A plain text box draws no vector scene, so these only matter\n // for a callout's leader/arrow/box-border (and the style toolbar's readout).\n const d = dto as Extract<AnnotationDTO, { subtype: 'free-text' }>;\n return {\n color: colorToCss(d.color),\n interiorColor: d.interiorColor ? colorToCss(d.interiorColor) : null,\n strokeWidth: d.strokeWidth,\n opacity: d.opacity,\n blendMode: dto.blendMode,\n border: borderFromDTO(d),\n };\n }\n if (dto.subtype === 'redact') {\n // `/C` is the marking-stage outline; `/IC` the fill painted on apply.\n // No `/BS` on redact — the outline weight is a client rendering choice.\n const d = dto as Extract<AnnotationDTO, { subtype: 'redact' }>;\n return {\n color: colorToCss(d.color),\n interiorColor: d.interiorColor ? colorToCss(d.interiorColor) : null,\n strokeWidth: 1.5,\n opacity: d.opacity,\n blendMode: dto.blendMode,\n border: { kind: 'solid' },\n };\n }\n if (dto.subtype === 'text' || dto.subtype === 'file-attachment') {\n // Icon kinds: /C is the icon fill, /CA its opacity — no stroke/fill split.\n const d = dto as Extract<AnnotationDTO, { color: Color; opacity: number }>;\n return {\n color: colorToCss(d.color),\n interiorColor: null,\n strokeWidth: 1,\n opacity: d.opacity,\n blendMode: dto.blendMode,\n border: { kind: 'solid' },\n };\n }\n return {\n color: '#444444',\n interiorColor: null,\n strokeWidth: 1,\n opacity: 1,\n blendMode: dto.blendMode,\n border: { kind: 'solid' },\n };\n}\n\n/**\n * The flat props vocabulary (CSS colours, house keys) → the engine's widget\n * appearance for `doc.forms` authoring — the SAME mapping the widget patch\n * lowering uses, exported as a boundary utility so the form plugin can style\n * `placeField` from a tool's `currentDefaults` without growing a second CSS\n * parser. Absent keys stay absent (the engine writes nothing for them).\n */\nexport function widgetAppearanceFromProps(props: AnnotationPropsPatch): WidgetAppearance {\n return {\n ...(props.color !== undefined ? { color: cssToColor(props.color) } : {}),\n ...(props.interiorColor !== undefined\n ? { interiorColor: props.interiorColor ? cssToColor(props.interiorColor) : null }\n : {}),\n ...(props.strokeWidth !== undefined ? { strokeWidth: props.strokeWidth } : {}),\n ...(props.border !== undefined\n ? { borderStyle: props.border.kind === 'dashed' ? ('dashed' as const) : ('solid' as const) }\n : {}),\n ...(props.fontFamily !== undefined ? { fontFamily: props.fontFamily as StandardFont } : {}),\n ...(props.fontSize !== undefined ? { fontSize: props.fontSize } : {}),\n ...(props.fontColor !== undefined ? { fontColor: cssToColor(props.fontColor) } : {}),\n ...(props.textAlign !== undefined ? { textAlign: props.textAlign } : {}),\n };\n}\n"],"mappings":"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"}
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
+
import { AnnotationFlags, AnnotationProps, AnnotationPropsPatch, ChromeNode, ClickCreate, CreationDraftAnchor, Geom, Id, InkStraightenOptions, Model, PropKey, PropSpec, Rect, RenderItem, SnapSettings, Subtype, TextEndAnchor, TextQuad, Vec, ViewEnv } from "@embedpdf/core-annotation";
|
|
2
|
+
import { AnnotationAppearanceImage, AnnotationDTO, AnnotationDraft, AnnotationPatch, AnnotationRef, AttachmentContent, AttachmentFileSource, BinarySource, CommentThread, InkIntent, PdfActionTree, PdfLinkTarget, PdfRect } from "@embedpdf/engine-core/runtime";
|
|
1
3
|
import { DocumentEvent, PageObjectNumber } from "@embedpdf/core";
|
|
4
|
+
import { AnnotCommitEntry, AnnotCommitResult } from "@embedpdf/plugin-actions/contract/host";
|
|
2
5
|
import { PageRotation } from "@embedpdf/core-geometry";
|
|
3
|
-
import { AnnotationAppearanceImage, AnnotationDTO, AnnotationDraft, AnnotationPatch, AnnotationRef, AttachmentContent, AttachmentFileSource, BinarySource, CommentThread, InkIntent, PdfLinkTarget, PdfRect } from "@embedpdf/engine-core/runtime";
|
|
4
|
-
import { AnnotationFlags, AnnotationProps, AnnotationPropsPatch, ChromeNode, ClickCreate, CreationDraftAnchor, Geom, Id, InkStraightenOptions, Model, PropKey, PropSpec, Rect, RenderItem, SnapSettings, Subtype, TextEndAnchor, TextQuad, Vec, ViewEnv } from "@embedpdf/core-annotation";
|
|
5
6
|
//#region src/tools.d.ts
|
|
6
7
|
/**
|
|
7
8
|
* How a stamp-family tool resolves the image bytes it places — pure DATA, so a
|
|
@@ -429,6 +430,19 @@ interface LinkNavItem {
|
|
|
429
430
|
* stays selectable/movable; standalone document links navigate regardless.
|
|
430
431
|
*/
|
|
431
432
|
attached: boolean;
|
|
433
|
+
/** The full payload-carrying `/A` tree, when one exists — the action
|
|
434
|
+
* engine's dispatch input. `target` remains its root projection. */
|
|
435
|
+
activate?: PdfActionTree;
|
|
436
|
+
/** The annotation ref, carried for ActionSource context. */
|
|
437
|
+
ref?: AnnotationRef;
|
|
438
|
+
/** Which `/AA` hover trees this link carries — the nav layer's pump flags
|
|
439
|
+
* (tree-less hover must cost zero dispatches). Links are behavior-inert
|
|
440
|
+
* to the annotation plane's hover feed while navigable, so THEIR
|
|
441
|
+
* cursorEnter/cursorExit can only fire from the LinkLayer anchors. */
|
|
442
|
+
hoverEvents?: {
|
|
443
|
+
enter: boolean;
|
|
444
|
+
exit: boolean;
|
|
445
|
+
};
|
|
432
446
|
}
|
|
433
447
|
interface Behavior {
|
|
434
448
|
id: string;
|
|
@@ -490,8 +504,9 @@ interface TextItem {
|
|
|
490
504
|
* package root (`@embedpdf/plugin-annotation`).
|
|
491
505
|
*
|
|
492
506
|
* Framework-only plumbing (render projection, pointer gestures, behavior
|
|
493
|
-
* registration) lives on {@link AnnotationHostCapability}, reachable
|
|
494
|
-
*
|
|
507
|
+
* registration) lives on {@link AnnotationHostCapability}, reachable through
|
|
508
|
+
* `@embedpdf/plugin-annotation/contract/host` (and the framework's `/internal`
|
|
509
|
+
* entry). Both are the SAME runtime
|
|
495
510
|
* object — two typed lenses on one token — so app code simply can't see the host
|
|
496
511
|
* methods.
|
|
497
512
|
*/
|
|
@@ -709,6 +724,13 @@ interface AnnotationCapability {
|
|
|
709
724
|
armStamp(input: StampToolInput): Promise<void>;
|
|
710
725
|
/** Drop the armed stamp payload (a tool change away from 'stamp' does this too). */
|
|
711
726
|
disarmStamp(): void;
|
|
727
|
+
/**
|
|
728
|
+
* Place a stamp WITHOUT the pointer: the same validation, fit, page clamp,
|
|
729
|
+
* `/Name`, and `/Subj` a click after {@link armStamp} produces — the one
|
|
730
|
+
* placement law, exposed for code. Resolves to the created annotation's
|
|
731
|
+
* ref; the placement is selected like a click's.
|
|
732
|
+
*/
|
|
733
|
+
placeStamp(input: StampToolInput, placement: StampPlacement): Promise<AnnotationRef>;
|
|
712
734
|
/**
|
|
713
735
|
* Install the ONE file-picker port every click-then-pick tool resolves
|
|
714
736
|
* through (see {@link FilePickerProvider}) — the stamp `'prompt'` source and
|
|
@@ -757,14 +779,18 @@ interface StampToolInput {
|
|
|
757
779
|
source: BinarySource;
|
|
758
780
|
/** Placed width in PDF points (height follows the intrinsic aspect). Default 150. */
|
|
759
781
|
targetWidth?: number;
|
|
782
|
+
/** The placed annotation's `/Name` — the stamp identifier (standard or custom). */
|
|
783
|
+
name?: string;
|
|
784
|
+
/** The placed annotation's `/Subj`. */
|
|
785
|
+
subject?: string;
|
|
760
786
|
/**
|
|
761
|
-
*
|
|
762
|
-
*
|
|
763
|
-
*
|
|
764
|
-
*
|
|
765
|
-
*
|
|
787
|
+
* The hover ghost's image. Either fixed bytes (PNG/JPEG) or — for vector
|
|
788
|
+
* sources, which are only ever right at ONE on-screen size — a
|
|
789
|
+
* {@link StampPreviewProvider} the ghost asks for a render at the device
|
|
790
|
+
* pixel width it is displayed at. Raster sources default to themselves;
|
|
791
|
+
* omit and the tool simply shows no ghost.
|
|
766
792
|
*/
|
|
767
|
-
preview?: BinarySource;
|
|
793
|
+
preview?: BinarySource | StampPreviewProvider;
|
|
768
794
|
/**
|
|
769
795
|
* The source's intrinsic size in PDF points. Raster sources are measured
|
|
770
796
|
* from their own header, but PDF bytes carry no sniffable dimensions —
|
|
@@ -782,6 +808,33 @@ interface ArmedStampPreview {
|
|
|
782
808
|
bytes: Uint8Array;
|
|
783
809
|
mimeType?: string;
|
|
784
810
|
}
|
|
811
|
+
/**
|
|
812
|
+
* Resolution-aware ghost preview: "give me this stamp at `devicePixelWidth`
|
|
813
|
+
* pixels wide". The annotation plugin buckets the request (see
|
|
814
|
+
* {@link previewBucket}) and caches per bucket for the arm's lifetime, so a
|
|
815
|
+
* zoom gesture never renders per frame and one render serves a zoom range.
|
|
816
|
+
* A stamp library renders its page lazily through its asset engine; a raster
|
|
817
|
+
* returns itself (it cannot get sharper than its pixels).
|
|
818
|
+
*/
|
|
819
|
+
type StampPreviewProvider = (devicePixelWidth: number) => Promise<ArmedStampPreview | null>;
|
|
820
|
+
/**
|
|
821
|
+
* Ghost render buckets: powers of two from 128 px up to `cap`. The same policy
|
|
822
|
+
* the page renderer uses — one bitmap per size class, never per zoom step.
|
|
823
|
+
*/
|
|
824
|
+
declare function previewBucket(devicePixelWidth: number, cap?: number): number;
|
|
825
|
+
/**
|
|
826
|
+
* Where a programmatic stamp placement lands — the inputs a click supplies.
|
|
827
|
+
* The box is fitted and clamped exactly as the click path does it.
|
|
828
|
+
*/
|
|
829
|
+
interface StampPlacement {
|
|
830
|
+
pageObjectNumber: PageObjectNumber;
|
|
831
|
+
/** Anchor in page points (content space): the placement is centred here. */
|
|
832
|
+
at: Vec;
|
|
833
|
+
/** Placed width in PDF points; default the payload's intrinsic size. */
|
|
834
|
+
targetWidth?: number;
|
|
835
|
+
/** Content rotation, degrees clockwise. Default 0. */
|
|
836
|
+
rotation?: number;
|
|
837
|
+
}
|
|
785
838
|
/**
|
|
786
839
|
* What the {@link FilePickerProvider} is asked for: which tool clicked (id +
|
|
787
840
|
* the kind it creates), the tool's `accept` filter, and the page-space point
|
|
@@ -818,8 +871,9 @@ type FilePickerProvider = (req: FilePromptRequest) => Promise<AttachmentFileSour
|
|
|
818
871
|
/**
|
|
819
872
|
* The HOST (framework) surface: everything the render layer, the interaction hub,
|
|
820
873
|
* and sibling plugins need, on top of the public {@link AnnotationCapability}.
|
|
821
|
-
*
|
|
822
|
-
*
|
|
874
|
+
* Host-only — sibling plugins import the token from
|
|
875
|
+
* `@embedpdf/plugin-annotation/contract/host`; framework implementation code may
|
|
876
|
+
* use `/internal`. Never use either from application code.
|
|
823
877
|
*/
|
|
824
878
|
interface AnnotationHostCapability extends AnnotationCapability {
|
|
825
879
|
/** `view` (the page's scale + total display rotation, from its transform)
|
|
@@ -1024,8 +1078,13 @@ interface AnnotationHostCapability extends AnnotationCapability {
|
|
|
1024
1078
|
* Vector ghosts also ride {@link pageItems}; only `kind: 'image'` ghosts
|
|
1025
1079
|
* need the framework's blit. */
|
|
1026
1080
|
toolGhost(pon: PageObjectNumber): ToolGhost | null;
|
|
1027
|
-
/**
|
|
1028
|
-
|
|
1081
|
+
/**
|
|
1082
|
+
* The armed stamp's paintable preview at (roughly) `devicePixelWidth`
|
|
1083
|
+
* pixels wide — bucketed and cached per bucket for the arm's lifetime —
|
|
1084
|
+
* or null when there is no ghost to show. Omit the width for the
|
|
1085
|
+
* smallest bucket.
|
|
1086
|
+
*/
|
|
1087
|
+
armedStampPreview(devicePixelWidth?: number): Promise<ArmedStampPreview | null>;
|
|
1029
1088
|
/** Bumps on arm/disarm — keys the render layer's preview object-URL lifetime. */
|
|
1030
1089
|
stampArmEpoch(): number;
|
|
1031
1090
|
/**
|
|
@@ -1046,13 +1105,25 @@ interface AnnotationHostCapability extends AnnotationCapability {
|
|
|
1046
1105
|
* gesture and the created annotation's PDF kind. Falls back to the id. */
|
|
1047
1106
|
toolSubtype(id: string): Subtype;
|
|
1048
1107
|
registerBehavior(b: Behavior): () => void;
|
|
1108
|
+
/**
|
|
1109
|
+
* The actions plane's session-visibility write (Hide actions, script
|
|
1110
|
+
* `annot.hidden`): resolve annotation OBJECT NUMBERS to loaded model ids
|
|
1111
|
+
* (the `obj:` refKey seam) and merge session-hidden overrides. Returns how
|
|
1112
|
+
* many resolved — unresolved numbers (unloaded pages, nm/index refs) are
|
|
1113
|
+
* the caller's diagnostics. Session state only; never an engine write.
|
|
1114
|
+
*/
|
|
1115
|
+
/** The script/Hide DOCUMENT-commit door (full ISO): engine updates +
|
|
1116
|
+
* model reconciliation, per entry, stop-on-failure. Never enqueues,
|
|
1117
|
+
* never touches the script host — the D2 sink contract. */
|
|
1118
|
+
commitScriptEffects(entries: AnnotCommitEntry[]): Promise<AnnotCommitResult>;
|
|
1049
1119
|
}
|
|
1050
1120
|
/**
|
|
1051
1121
|
* The annotation capability token. Typed to the full {@link AnnotationHostCapability}
|
|
1052
|
-
* here (the package internals
|
|
1053
|
-
* root re-exports the SAME token narrowed to
|
|
1122
|
+
* here (the package internals, `/contract/host`, and `/internal` use this view).
|
|
1123
|
+
* The package root re-exports the SAME token narrowed to
|
|
1124
|
+
* {@link AnnotationCapability}.
|
|
1054
1125
|
*/
|
|
1055
1126
|
declare const AnnotationToken: import("@embedpdf/core").CapabilityToken<AnnotationHostCapability>;
|
|
1056
1127
|
//#endregion
|
|
1057
|
-
export {
|
|
1058
|
-
//# sourceMappingURL=types-
|
|
1128
|
+
export { PromptSourceSpec as A, ToolGhost as C, DEFAULT_TOOLS as D, AnnotationToolInput as E, ToolDefaultsFor as F, buildToolRegistry as I, SelectionAuthoring as M, StampSourceSpec as N, GhostPolicy as O, ToolAuthoringKind as P, ThreadDeleteResult as S, AnnotationToolDef as T, SelectionProps as _, AnnotationHydration as a, StampToolInput as b, Behavior as c, CommentPermissions as d, CommentsApi as f, SelectionFlags as g, LinkNavItem as h, AnnotationHostCapability as i, ResolvedTool as j, InkAuthoringOptions as k, ChromeSettings as l, FilePromptRequest as m, AnnotationCapability as n, AnnotationState as o, FilePickerProvider as p, AnnotationConfig as r, AnnotationToken as s, AnnotationAction as t, ChromeSettingsPatch as u, StampPlacement as v, previewBucket as w, TextItem as x, StampPreviewProvider as y };
|
|
1129
|
+
//# sourceMappingURL=types-BAPdbfPT.d.cts.map
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { DocumentEvent, PageObjectNumber } from "@embedpdf/core";
|
|
2
|
-
import {
|
|
2
|
+
import { AnnotCommitEntry, AnnotCommitResult } from "@embedpdf/plugin-actions/contract/host";
|
|
3
|
+
import { AnnotationAppearanceImage, AnnotationDTO, AnnotationDraft, AnnotationPatch, AnnotationRef, AttachmentContent, AttachmentFileSource, BinarySource, CommentThread, InkIntent, PdfActionTree, PdfLinkTarget, PdfRect } from "@embedpdf/engine-core/runtime";
|
|
3
4
|
import { AnnotationFlags, AnnotationProps, AnnotationPropsPatch, ChromeNode, ClickCreate, CreationDraftAnchor, Geom, Id, InkStraightenOptions, Model, PropKey, PropSpec, Rect, RenderItem, SnapSettings, Subtype, TextEndAnchor, TextQuad, Vec, ViewEnv } from "@embedpdf/core-annotation";
|
|
4
5
|
import { PageRotation } from "@embedpdf/core-geometry";
|
|
5
6
|
//#region src/tools.d.ts
|
|
@@ -429,6 +430,19 @@ interface LinkNavItem {
|
|
|
429
430
|
* stays selectable/movable; standalone document links navigate regardless.
|
|
430
431
|
*/
|
|
431
432
|
attached: boolean;
|
|
433
|
+
/** The full payload-carrying `/A` tree, when one exists — the action
|
|
434
|
+
* engine's dispatch input. `target` remains its root projection. */
|
|
435
|
+
activate?: PdfActionTree;
|
|
436
|
+
/** The annotation ref, carried for ActionSource context. */
|
|
437
|
+
ref?: AnnotationRef;
|
|
438
|
+
/** Which `/AA` hover trees this link carries — the nav layer's pump flags
|
|
439
|
+
* (tree-less hover must cost zero dispatches). Links are behavior-inert
|
|
440
|
+
* to the annotation plane's hover feed while navigable, so THEIR
|
|
441
|
+
* cursorEnter/cursorExit can only fire from the LinkLayer anchors. */
|
|
442
|
+
hoverEvents?: {
|
|
443
|
+
enter: boolean;
|
|
444
|
+
exit: boolean;
|
|
445
|
+
};
|
|
432
446
|
}
|
|
433
447
|
interface Behavior {
|
|
434
448
|
id: string;
|
|
@@ -490,8 +504,9 @@ interface TextItem {
|
|
|
490
504
|
* package root (`@embedpdf/plugin-annotation`).
|
|
491
505
|
*
|
|
492
506
|
* Framework-only plumbing (render projection, pointer gestures, behavior
|
|
493
|
-
* registration) lives on {@link AnnotationHostCapability}, reachable
|
|
494
|
-
*
|
|
507
|
+
* registration) lives on {@link AnnotationHostCapability}, reachable through
|
|
508
|
+
* `@embedpdf/plugin-annotation/contract/host` (and the framework's `/internal`
|
|
509
|
+
* entry). Both are the SAME runtime
|
|
495
510
|
* object — two typed lenses on one token — so app code simply can't see the host
|
|
496
511
|
* methods.
|
|
497
512
|
*/
|
|
@@ -709,6 +724,13 @@ interface AnnotationCapability {
|
|
|
709
724
|
armStamp(input: StampToolInput): Promise<void>;
|
|
710
725
|
/** Drop the armed stamp payload (a tool change away from 'stamp' does this too). */
|
|
711
726
|
disarmStamp(): void;
|
|
727
|
+
/**
|
|
728
|
+
* Place a stamp WITHOUT the pointer: the same validation, fit, page clamp,
|
|
729
|
+
* `/Name`, and `/Subj` a click after {@link armStamp} produces — the one
|
|
730
|
+
* placement law, exposed for code. Resolves to the created annotation's
|
|
731
|
+
* ref; the placement is selected like a click's.
|
|
732
|
+
*/
|
|
733
|
+
placeStamp(input: StampToolInput, placement: StampPlacement): Promise<AnnotationRef>;
|
|
712
734
|
/**
|
|
713
735
|
* Install the ONE file-picker port every click-then-pick tool resolves
|
|
714
736
|
* through (see {@link FilePickerProvider}) — the stamp `'prompt'` source and
|
|
@@ -757,14 +779,18 @@ interface StampToolInput {
|
|
|
757
779
|
source: BinarySource;
|
|
758
780
|
/** Placed width in PDF points (height follows the intrinsic aspect). Default 150. */
|
|
759
781
|
targetWidth?: number;
|
|
782
|
+
/** The placed annotation's `/Name` — the stamp identifier (standard or custom). */
|
|
783
|
+
name?: string;
|
|
784
|
+
/** The placed annotation's `/Subj`. */
|
|
785
|
+
subject?: string;
|
|
760
786
|
/**
|
|
761
|
-
*
|
|
762
|
-
*
|
|
763
|
-
*
|
|
764
|
-
*
|
|
765
|
-
*
|
|
787
|
+
* The hover ghost's image. Either fixed bytes (PNG/JPEG) or — for vector
|
|
788
|
+
* sources, which are only ever right at ONE on-screen size — a
|
|
789
|
+
* {@link StampPreviewProvider} the ghost asks for a render at the device
|
|
790
|
+
* pixel width it is displayed at. Raster sources default to themselves;
|
|
791
|
+
* omit and the tool simply shows no ghost.
|
|
766
792
|
*/
|
|
767
|
-
preview?: BinarySource;
|
|
793
|
+
preview?: BinarySource | StampPreviewProvider;
|
|
768
794
|
/**
|
|
769
795
|
* The source's intrinsic size in PDF points. Raster sources are measured
|
|
770
796
|
* from their own header, but PDF bytes carry no sniffable dimensions —
|
|
@@ -782,6 +808,33 @@ interface ArmedStampPreview {
|
|
|
782
808
|
bytes: Uint8Array;
|
|
783
809
|
mimeType?: string;
|
|
784
810
|
}
|
|
811
|
+
/**
|
|
812
|
+
* Resolution-aware ghost preview: "give me this stamp at `devicePixelWidth`
|
|
813
|
+
* pixels wide". The annotation plugin buckets the request (see
|
|
814
|
+
* {@link previewBucket}) and caches per bucket for the arm's lifetime, so a
|
|
815
|
+
* zoom gesture never renders per frame and one render serves a zoom range.
|
|
816
|
+
* A stamp library renders its page lazily through its asset engine; a raster
|
|
817
|
+
* returns itself (it cannot get sharper than its pixels).
|
|
818
|
+
*/
|
|
819
|
+
type StampPreviewProvider = (devicePixelWidth: number) => Promise<ArmedStampPreview | null>;
|
|
820
|
+
/**
|
|
821
|
+
* Ghost render buckets: powers of two from 128 px up to `cap`. The same policy
|
|
822
|
+
* the page renderer uses — one bitmap per size class, never per zoom step.
|
|
823
|
+
*/
|
|
824
|
+
declare function previewBucket(devicePixelWidth: number, cap?: number): number;
|
|
825
|
+
/**
|
|
826
|
+
* Where a programmatic stamp placement lands — the inputs a click supplies.
|
|
827
|
+
* The box is fitted and clamped exactly as the click path does it.
|
|
828
|
+
*/
|
|
829
|
+
interface StampPlacement {
|
|
830
|
+
pageObjectNumber: PageObjectNumber;
|
|
831
|
+
/** Anchor in page points (content space): the placement is centred here. */
|
|
832
|
+
at: Vec;
|
|
833
|
+
/** Placed width in PDF points; default the payload's intrinsic size. */
|
|
834
|
+
targetWidth?: number;
|
|
835
|
+
/** Content rotation, degrees clockwise. Default 0. */
|
|
836
|
+
rotation?: number;
|
|
837
|
+
}
|
|
785
838
|
/**
|
|
786
839
|
* What the {@link FilePickerProvider} is asked for: which tool clicked (id +
|
|
787
840
|
* the kind it creates), the tool's `accept` filter, and the page-space point
|
|
@@ -818,8 +871,9 @@ type FilePickerProvider = (req: FilePromptRequest) => Promise<AttachmentFileSour
|
|
|
818
871
|
/**
|
|
819
872
|
* The HOST (framework) surface: everything the render layer, the interaction hub,
|
|
820
873
|
* and sibling plugins need, on top of the public {@link AnnotationCapability}.
|
|
821
|
-
*
|
|
822
|
-
*
|
|
874
|
+
* Host-only — sibling plugins import the token from
|
|
875
|
+
* `@embedpdf/plugin-annotation/contract/host`; framework implementation code may
|
|
876
|
+
* use `/internal`. Never use either from application code.
|
|
823
877
|
*/
|
|
824
878
|
interface AnnotationHostCapability extends AnnotationCapability {
|
|
825
879
|
/** `view` (the page's scale + total display rotation, from its transform)
|
|
@@ -1024,8 +1078,13 @@ interface AnnotationHostCapability extends AnnotationCapability {
|
|
|
1024
1078
|
* Vector ghosts also ride {@link pageItems}; only `kind: 'image'` ghosts
|
|
1025
1079
|
* need the framework's blit. */
|
|
1026
1080
|
toolGhost(pon: PageObjectNumber): ToolGhost | null;
|
|
1027
|
-
/**
|
|
1028
|
-
|
|
1081
|
+
/**
|
|
1082
|
+
* The armed stamp's paintable preview at (roughly) `devicePixelWidth`
|
|
1083
|
+
* pixels wide — bucketed and cached per bucket for the arm's lifetime —
|
|
1084
|
+
* or null when there is no ghost to show. Omit the width for the
|
|
1085
|
+
* smallest bucket.
|
|
1086
|
+
*/
|
|
1087
|
+
armedStampPreview(devicePixelWidth?: number): Promise<ArmedStampPreview | null>;
|
|
1029
1088
|
/** Bumps on arm/disarm — keys the render layer's preview object-URL lifetime. */
|
|
1030
1089
|
stampArmEpoch(): number;
|
|
1031
1090
|
/**
|
|
@@ -1046,13 +1105,25 @@ interface AnnotationHostCapability extends AnnotationCapability {
|
|
|
1046
1105
|
* gesture and the created annotation's PDF kind. Falls back to the id. */
|
|
1047
1106
|
toolSubtype(id: string): Subtype;
|
|
1048
1107
|
registerBehavior(b: Behavior): () => void;
|
|
1108
|
+
/**
|
|
1109
|
+
* The actions plane's session-visibility write (Hide actions, script
|
|
1110
|
+
* `annot.hidden`): resolve annotation OBJECT NUMBERS to loaded model ids
|
|
1111
|
+
* (the `obj:` refKey seam) and merge session-hidden overrides. Returns how
|
|
1112
|
+
* many resolved — unresolved numbers (unloaded pages, nm/index refs) are
|
|
1113
|
+
* the caller's diagnostics. Session state only; never an engine write.
|
|
1114
|
+
*/
|
|
1115
|
+
/** The script/Hide DOCUMENT-commit door (full ISO): engine updates +
|
|
1116
|
+
* model reconciliation, per entry, stop-on-failure. Never enqueues,
|
|
1117
|
+
* never touches the script host — the D2 sink contract. */
|
|
1118
|
+
commitScriptEffects(entries: AnnotCommitEntry[]): Promise<AnnotCommitResult>;
|
|
1049
1119
|
}
|
|
1050
1120
|
/**
|
|
1051
1121
|
* The annotation capability token. Typed to the full {@link AnnotationHostCapability}
|
|
1052
|
-
* here (the package internals
|
|
1053
|
-
* root re-exports the SAME token narrowed to
|
|
1122
|
+
* here (the package internals, `/contract/host`, and `/internal` use this view).
|
|
1123
|
+
* The package root re-exports the SAME token narrowed to
|
|
1124
|
+
* {@link AnnotationCapability}.
|
|
1054
1125
|
*/
|
|
1055
1126
|
declare const AnnotationToken: import("@embedpdf/core").CapabilityToken<AnnotationHostCapability>;
|
|
1056
1127
|
//#endregion
|
|
1057
|
-
export {
|
|
1058
|
-
//# sourceMappingURL=types-
|
|
1128
|
+
export { PromptSourceSpec as A, ToolGhost as C, DEFAULT_TOOLS as D, AnnotationToolInput as E, ToolDefaultsFor as F, buildToolRegistry as I, SelectionAuthoring as M, StampSourceSpec as N, GhostPolicy as O, ToolAuthoringKind as P, ThreadDeleteResult as S, AnnotationToolDef as T, SelectionProps as _, AnnotationHydration as a, StampToolInput as b, Behavior as c, CommentPermissions as d, CommentsApi as f, SelectionFlags as g, LinkNavItem as h, AnnotationHostCapability as i, ResolvedTool as j, InkAuthoringOptions as k, ChromeSettings as l, FilePromptRequest as m, AnnotationCapability as n, AnnotationState as o, FilePickerProvider as p, AnnotationConfig as r, AnnotationToken as s, AnnotationAction as t, ChromeSettingsPatch as u, StampPlacement as v, previewBucket as w, TextItem as x, StampPreviewProvider as y };
|
|
1129
|
+
//# sourceMappingURL=types-BgetZ4BK.d.ts.map
|