@reekon-tools/boldr-utils 1.22.0 → 1.24.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/annotation/canvas/pdfCanvasPages.d.ts +25 -0
- package/dist/annotation/canvas/pdfCanvasPages.js +255 -0
- package/dist/annotation/data/AnnotationDataProvider.d.ts +6 -0
- package/dist/annotation/data/InMemoryAnnotationProvider.d.ts +6 -0
- package/dist/annotation/data/InMemoryAnnotationProvider.js +25 -0
- package/dist/annotation/data/hooks/usePdfCanvasDoc.d.ts +29 -0
- package/dist/annotation/data/hooks/usePdfCanvasDoc.js +344 -0
- package/dist/export/pdf/annots.d.ts +23 -0
- package/dist/export/pdf/annots.js +135 -0
- package/dist/export/pdf/decrypt.d.ts +21 -0
- package/dist/export/pdf/decrypt.js +121 -0
- package/dist/export/pdf/fonts.d.ts +3 -4
- package/dist/export/pdf/fonts.js +2 -14
- package/dist/export/pdf/index.d.ts +4 -2
- package/dist/export/pdf/index.js +3 -1
- package/dist/export/pdf/marks.d.ts +66 -5
- package/dist/export/pdf/marks.js +150 -7
- package/dist/export/pdf/pageMapping.d.ts +2 -0
- package/dist/export/pdf/pageMapping.js +10 -0
- package/dist/export/pdf/renderCanvasToPdf.d.ts +9 -1
- package/dist/export/pdf/renderCanvasToPdf.js +303 -120
- package/dist/export/pdf/resources.d.ts +35 -0
- package/dist/export/pdf/resources.js +95 -0
- package/dist/export/pdf/tiles.d.ts +5 -9
- package/dist/export/pdf/tiles.js +20 -20
- package/dist/export/pdf/types.d.ts +25 -1
- package/dist/exports.d.ts +3 -0
- package/dist/exports.js +3 -0
- package/dist/server.d.ts +2 -0
- package/dist/server.js +2 -0
- package/dist/types/firestore.d.ts +6 -0
- package/dist/types/firestore.js +5 -0
- package/dist/types/pdfCanvas.d.ts +38 -0
- package/dist/types/pdfCanvas.js +16 -0
- package/package.json +6 -1
package/dist/export/pdf/fonts.js
CHANGED
|
@@ -10,7 +10,6 @@ export class PdfFonts {
|
|
|
10
10
|
constructor(primary, fallback) {
|
|
11
11
|
this.primary = primary;
|
|
12
12
|
this.fallback = fallback;
|
|
13
|
-
this.keys = new Map();
|
|
14
13
|
}
|
|
15
14
|
static async create(doc, primaryBytes) {
|
|
16
15
|
doc.registerFontkit(fontkit);
|
|
@@ -52,23 +51,12 @@ export class PdfFonts {
|
|
|
52
51
|
const p = this.pick(text);
|
|
53
52
|
return p.text ? p.font.widthOfTextAtSize(p.text, size) : 0;
|
|
54
53
|
}
|
|
55
|
-
keyFor(page, font) {
|
|
56
|
-
let keys = this.keys.get(page);
|
|
57
|
-
if (!keys) {
|
|
58
|
-
keys = {
|
|
59
|
-
primary: page.node.newFontDictionary(this.primary.name, this.primary.ref),
|
|
60
|
-
fallback: page.node.newFontDictionary(this.fallback.name, this.fallback.ref),
|
|
61
|
-
};
|
|
62
|
-
this.keys.set(page, keys);
|
|
63
|
-
}
|
|
64
|
-
return font === this.primary ? keys.primary : keys.fallback;
|
|
65
|
-
}
|
|
66
54
|
/**
|
|
67
55
|
* Operators drawing one line of text in a y-DOWN space, with its baseline at
|
|
68
56
|
* `yBaseline` and its left / centre / right edge at `x`. Returns [] when
|
|
69
57
|
* nothing of the text is drawable.
|
|
70
58
|
*/
|
|
71
|
-
textOps(
|
|
59
|
+
textOps(scope, text, size, color, x, yBaseline, options = {}) {
|
|
72
60
|
const picked = this.pick(text);
|
|
73
61
|
if (!picked.text || size <= 0)
|
|
74
62
|
return [];
|
|
@@ -77,7 +65,7 @@ export class PdfFonts {
|
|
|
77
65
|
const left = align === 'center' ? x - w / 2 : align === 'right' ? x - w : x;
|
|
78
66
|
return withMatrix(uprightAt(left, yBaseline), drawText(picked.font.encodeText(picked.text), {
|
|
79
67
|
color: parseHexColor(color).rgb,
|
|
80
|
-
font:
|
|
68
|
+
font: scope.fontKey(picked.font),
|
|
81
69
|
size,
|
|
82
70
|
rotate: degrees(0),
|
|
83
71
|
xSkew: degrees(0),
|
|
@@ -1,5 +1,7 @@
|
|
|
1
|
-
export { renderCanvasToPdf } from './renderCanvasToPdf.js';
|
|
1
|
+
export { renderCanvasToPdf, renderPdfCanvasToPdf, } from './renderCanvasToPdf.js';
|
|
2
|
+
export { stripPdfEncryption, type StripPdfEncryptionOptions, type StripPdfEncryptionResult, } from './decrypt.js';
|
|
2
3
|
export { docToPageMatrix, pageRectsOf, normalizeRotation, rotatedBoxSize, applyMatrix, type AffineMatrix, type PageRotation, type PdfBox, } from './pageMapping.js';
|
|
3
4
|
export { resolveTileContent, measurementTileFillFor, FORMULA_COLUMN_TILE_FILL, PLANE_COMPUTED_TILE_FILL, type TileFileInfo, type TileResolutionContext, } from './tileContent.js';
|
|
4
5
|
export { tileFootprint, type TileFootprint } from './tiles.js';
|
|
5
|
-
export {
|
|
6
|
+
export { annotationCount } from './annots.js';
|
|
7
|
+
export { PdfExportError, type EmbeddedImage, type PdfExportCalibration, type RenderCanvasToPdfInput, type RenderPdfCanvasToPdfInput, type RenderCanvasToPdfResult, type ResolvedTileContent, type MeasurementTileContent, type LiteralTileContent, type EmptyTileContent, type HeaderTileContent, type ObjectTileContent, type PlaneDimensionTileContent, type InstructionsTileContent, type SkippedItem, } from './types.js';
|
package/dist/export/pdf/index.js
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
|
-
export { renderCanvasToPdf } from './renderCanvasToPdf.js';
|
|
1
|
+
export { renderCanvasToPdf, renderPdfCanvasToPdf, } from './renderCanvasToPdf.js';
|
|
2
|
+
export { stripPdfEncryption, } from './decrypt.js';
|
|
2
3
|
export { docToPageMatrix, pageRectsOf, normalizeRotation, rotatedBoxSize, applyMatrix, } from './pageMapping.js';
|
|
3
4
|
export { resolveTileContent, measurementTileFillFor, FORMULA_COLUMN_TILE_FILL, PLANE_COMPUTED_TILE_FILL, } from './tileContent.js';
|
|
4
5
|
export { tileFootprint } from './tiles.js';
|
|
6
|
+
export { annotationCount } from './annots.js';
|
|
5
7
|
export { PdfExportError, } from './types.js';
|
|
@@ -1,16 +1,73 @@
|
|
|
1
|
-
import { type
|
|
2
|
-
import type { AnnotationShape, AnnotationStroke, PlacedMeasurementRef } from '../../types/annotation.js';
|
|
1
|
+
import { type PDFOperator } from 'pdf-lib';
|
|
2
|
+
import type { AnnotationShape, AnnotationStroke, PlacedMeasurementRef, Vec2 } from '../../types/annotation.js';
|
|
3
3
|
import { dashIntervals } from '../../annotation/canvas/strokeGeometry.js';
|
|
4
4
|
import type { PdfFonts } from './fonts.js';
|
|
5
5
|
import { type DocRect } from './pageMapping.js';
|
|
6
|
+
import type { ResourceScope } from './resources.js';
|
|
6
7
|
import type { SkippedItem } from './types.js';
|
|
7
8
|
export interface MarkContext {
|
|
8
|
-
|
|
9
|
+
/** Where fonts, images and opacity states get registered. */
|
|
10
|
+
scope: ResourceScope;
|
|
9
11
|
fonts: PdfFonts;
|
|
10
|
-
/** An ExtGState carrying `alpha` (CA/ca) for this page; undefined at 1. */
|
|
11
|
-
alphaState: (alpha: number) => PDFName | undefined;
|
|
12
12
|
skipped: SkippedItem[];
|
|
13
13
|
}
|
|
14
|
+
/**
|
|
15
|
+
* What an element IS, for the annotation dictionary that wraps its
|
|
16
|
+
* appearance stream in annotation mode: the standard fields a viewer reads
|
|
17
|
+
* back (and regenerates from after an edit). Points and rects are in DOC
|
|
18
|
+
* space; the annotation builder maps them onto the page.
|
|
19
|
+
*/
|
|
20
|
+
export type AnnotMeta = {
|
|
21
|
+
subtype: 'Ink';
|
|
22
|
+
color: string;
|
|
23
|
+
width: number;
|
|
24
|
+
alpha: number;
|
|
25
|
+
paths: Vec2[][];
|
|
26
|
+
} | {
|
|
27
|
+
subtype: 'Line';
|
|
28
|
+
color: string;
|
|
29
|
+
width: number;
|
|
30
|
+
alpha: number;
|
|
31
|
+
dash: boolean;
|
|
32
|
+
a: Vec2;
|
|
33
|
+
b: Vec2;
|
|
34
|
+
startArrow: boolean;
|
|
35
|
+
endArrow: boolean;
|
|
36
|
+
} | {
|
|
37
|
+
subtype: 'Square' | 'Circle';
|
|
38
|
+
color: string;
|
|
39
|
+
fill?: string;
|
|
40
|
+
width: number;
|
|
41
|
+
alpha: number;
|
|
42
|
+
dash: boolean;
|
|
43
|
+
rect: DocRect;
|
|
44
|
+
} | {
|
|
45
|
+
subtype: 'Polygon' | 'PolyLine';
|
|
46
|
+
color: string;
|
|
47
|
+
fill?: string;
|
|
48
|
+
width: number;
|
|
49
|
+
alpha: number;
|
|
50
|
+
dash: boolean;
|
|
51
|
+
vertices: Vec2[];
|
|
52
|
+
startArrow: boolean;
|
|
53
|
+
endArrow: boolean;
|
|
54
|
+
} | {
|
|
55
|
+
subtype: 'FreeText';
|
|
56
|
+
color: string;
|
|
57
|
+
fontSize: number;
|
|
58
|
+
text: string;
|
|
59
|
+
alpha: number;
|
|
60
|
+
} | {
|
|
61
|
+
subtype: 'Stamp';
|
|
62
|
+
contents?: string;
|
|
63
|
+
};
|
|
64
|
+
/** One drawable element: its operators, its doc-space bounds, its identity. */
|
|
65
|
+
export interface Mark {
|
|
66
|
+
id: string;
|
|
67
|
+
ops: PDFOperator[];
|
|
68
|
+
bounds: DocRect;
|
|
69
|
+
annot: AnnotMeta;
|
|
70
|
+
}
|
|
14
71
|
export declare const strokeBounds: (s: AnnotationStroke) => DocRect | null;
|
|
15
72
|
export declare const strokeOps: (s: AnnotationStroke, ctx: MarkContext) => PDFOperator[];
|
|
16
73
|
export declare const shapeBounds: (shape: AnnotationShape) => DocRect | null;
|
|
@@ -18,3 +75,7 @@ export declare const shapeOps: (shape: AnnotationShape, ctx: MarkContext) => PDF
|
|
|
18
75
|
export declare const measurementMarkBounds: (placed: PlacedMeasurementRef) => DocRect | null;
|
|
19
76
|
export declare const measurementMarkOps: (placed: PlacedMeasurementRef, ctx: MarkContext) => PDFOperator[];
|
|
20
77
|
export { dashIntervals };
|
|
78
|
+
export declare const strokeMark: (s: AnnotationStroke, ctx: MarkContext) => Mark | null;
|
|
79
|
+
export declare const shapeMark: (shape: AnnotationShape, ctx: MarkContext) => Mark | null;
|
|
80
|
+
/** The measurement annotation's line / rectangle (not its tile). */
|
|
81
|
+
export declare const measurementMark: (placed: PlacedMeasurementRef, ctx: MarkContext) => Mark | null;
|
package/dist/export/pdf/marks.js
CHANGED
|
@@ -66,7 +66,7 @@ export const strokeOps = (s, ctx) => {
|
|
|
66
66
|
return [];
|
|
67
67
|
const opacity = s.tool === 'highlighter' ? 0.3 : 1;
|
|
68
68
|
const alpha = opacity * parseHexColor(s.color).alpha;
|
|
69
|
-
const gs = ctx.alphaState(alpha);
|
|
69
|
+
const gs = ctx.scope.alphaState(alpha);
|
|
70
70
|
const isDot = n === 4 && s.points[0] === s.points[2] && s.points[1] === s.points[3];
|
|
71
71
|
if (isDot) {
|
|
72
72
|
// Skia paints a zero-length round-capped contour as a dot; PDF only does
|
|
@@ -137,7 +137,7 @@ const textShapeOps = (shape, ctx) => {
|
|
|
137
137
|
const colorStr = shape.style.stroke ?? '#000000';
|
|
138
138
|
const decoration = shape.style.textDecoration;
|
|
139
139
|
const glyphColor = decoration === 'highlight' ? highlightTextColor(colorStr) : colorStr;
|
|
140
|
-
const gs = ctx.alphaState(parseHexColor(colorStr).alpha);
|
|
140
|
+
const gs = ctx.scope.alphaState(parseHexColor(colorStr).alpha);
|
|
141
141
|
const lineHeight = TEXT_LINE_HEIGHT_FACTOR * fontSize;
|
|
142
142
|
const ops = [];
|
|
143
143
|
let lost = false;
|
|
@@ -151,7 +151,7 @@ const textShapeOps = (shape, ctx) => {
|
|
|
151
151
|
if (decoration === 'highlight' && width > 0) {
|
|
152
152
|
ops.push(pushGraphicsState(), ...fillStateOps(colorStr, gs), rectangle(origin.x, top, width, lineHeight), fill(), popGraphicsState());
|
|
153
153
|
}
|
|
154
|
-
ops.push(...ctx.fonts.textOps(ctx.
|
|
154
|
+
ops.push(...ctx.fonts.textOps(ctx.scope, line, fontSize, glyphColor, origin.x, baseline, {
|
|
155
155
|
graphicsState: gs,
|
|
156
156
|
}));
|
|
157
157
|
if ((decoration === 'underline' || decoration === 'squiggle') &&
|
|
@@ -177,7 +177,7 @@ export const shapeOps = (shape, ctx) => {
|
|
|
177
177
|
return textShapeOps(shape, ctx);
|
|
178
178
|
const strokeColor = style.stroke ?? '#000000';
|
|
179
179
|
const strokeWidth = style.strokeWidth ?? 2;
|
|
180
|
-
const gs = ctx.alphaState(parseHexColor(strokeColor).alpha);
|
|
180
|
+
const gs = ctx.scope.alphaState(parseHexColor(strokeColor).alpha);
|
|
181
181
|
const closed = geometry.closed !== false;
|
|
182
182
|
const pts = geometry.points;
|
|
183
183
|
const strokeWith = (pathOps, join, cap) => [
|
|
@@ -197,7 +197,7 @@ export const shapeOps = (shape, ctx) => {
|
|
|
197
197
|
const fillWith = (pathOps) => style.fill
|
|
198
198
|
? [
|
|
199
199
|
pushGraphicsState(),
|
|
200
|
-
...fillStateOps(style.fill, ctx.alphaState(parseHexColor(style.fill).alpha)),
|
|
200
|
+
...fillStateOps(style.fill, ctx.scope.alphaState(parseHexColor(style.fill).alpha)),
|
|
201
201
|
...pathOps,
|
|
202
202
|
fill(),
|
|
203
203
|
popGraphicsState(),
|
|
@@ -298,7 +298,7 @@ export const measurementMarkOps = (placed, ctx) => {
|
|
|
298
298
|
width,
|
|
299
299
|
join: 'miter',
|
|
300
300
|
dash: !!placed.lineDash,
|
|
301
|
-
graphicsState: ctx.alphaState(parseHexColor(color).alpha),
|
|
301
|
+
graphicsState: ctx.scope.alphaState(parseHexColor(color).alpha),
|
|
302
302
|
}),
|
|
303
303
|
...rectPathOps(n.minX, n.minY, n.maxX - n.minX, n.maxY - n.minY),
|
|
304
304
|
stroke(),
|
|
@@ -309,7 +309,7 @@ export const measurementMarkOps = (placed, ctx) => {
|
|
|
309
309
|
const { a, b } = placed.line;
|
|
310
310
|
const color = placed.lineColor ?? MEASUREMENT_LINE_COLOR;
|
|
311
311
|
const width = placed.lineWidth ?? MEASUREMENT_LINE_WIDTH;
|
|
312
|
-
const gs = ctx.alphaState(parseHexColor(color).alpha);
|
|
312
|
+
const gs = ctx.scope.alphaState(parseHexColor(color).alpha);
|
|
313
313
|
const ops = [
|
|
314
314
|
pushGraphicsState(),
|
|
315
315
|
...strokeStateOps({
|
|
@@ -334,3 +334,146 @@ export const measurementMarkOps = (placed, ctx) => {
|
|
|
334
334
|
};
|
|
335
335
|
// Re-exported so the renderer can size dash tests without a second import.
|
|
336
336
|
export { dashIntervals };
|
|
337
|
+
/* ------------------------------------------------------------------ *
|
|
338
|
+
* Marks: ops + bounds + annotation metadata, per element
|
|
339
|
+
* ------------------------------------------------------------------ */
|
|
340
|
+
const strokePaths = (s) => {
|
|
341
|
+
const pts = [];
|
|
342
|
+
for (let i = 0; i + 1 < s.points.length; i += 2) {
|
|
343
|
+
pts.push({ x: s.points[i], y: s.points[i + 1] });
|
|
344
|
+
}
|
|
345
|
+
return pts;
|
|
346
|
+
};
|
|
347
|
+
export const strokeMark = (s, ctx) => {
|
|
348
|
+
const bounds = strokeBounds(s);
|
|
349
|
+
if (!bounds)
|
|
350
|
+
return null;
|
|
351
|
+
const opacity = s.tool === 'highlighter' ? 0.3 : 1;
|
|
352
|
+
return {
|
|
353
|
+
id: s.id,
|
|
354
|
+
ops: strokeOps(s, ctx),
|
|
355
|
+
bounds,
|
|
356
|
+
annot: {
|
|
357
|
+
subtype: 'Ink',
|
|
358
|
+
color: s.color,
|
|
359
|
+
width: s.width,
|
|
360
|
+
alpha: opacity * parseHexColor(s.color).alpha,
|
|
361
|
+
paths: [strokePaths(s)],
|
|
362
|
+
},
|
|
363
|
+
};
|
|
364
|
+
};
|
|
365
|
+
export const shapeMark = (shape, ctx) => {
|
|
366
|
+
const bounds = shapeBounds(shape);
|
|
367
|
+
if (!bounds)
|
|
368
|
+
return null;
|
|
369
|
+
const ops = shapeOps(shape, ctx);
|
|
370
|
+
const { kind, geometry, style } = shape;
|
|
371
|
+
const color = style.stroke ?? '#000000';
|
|
372
|
+
const width = style.strokeWidth ?? 2;
|
|
373
|
+
const alpha = parseHexColor(color).alpha;
|
|
374
|
+
const dash = !!style.dash;
|
|
375
|
+
const pts = geometry.points;
|
|
376
|
+
let annot;
|
|
377
|
+
switch (kind) {
|
|
378
|
+
case 'rect':
|
|
379
|
+
case 'ellipse': {
|
|
380
|
+
const b = visualShapeBounds(shape);
|
|
381
|
+
annot = {
|
|
382
|
+
subtype: kind === 'rect' ? 'Square' : 'Circle',
|
|
383
|
+
color,
|
|
384
|
+
fill: style.fill,
|
|
385
|
+
width,
|
|
386
|
+
alpha,
|
|
387
|
+
dash,
|
|
388
|
+
rect: boundsToRect(b),
|
|
389
|
+
};
|
|
390
|
+
break;
|
|
391
|
+
}
|
|
392
|
+
case 'line':
|
|
393
|
+
case 'arrow':
|
|
394
|
+
annot = {
|
|
395
|
+
subtype: 'Line',
|
|
396
|
+
color,
|
|
397
|
+
width,
|
|
398
|
+
alpha,
|
|
399
|
+
dash,
|
|
400
|
+
a: pts[0],
|
|
401
|
+
b: pts[1],
|
|
402
|
+
startArrow: style.startCap === 'arrow',
|
|
403
|
+
endArrow: kind === 'arrow' || style.cap === 'arrow',
|
|
404
|
+
};
|
|
405
|
+
break;
|
|
406
|
+
case 'polygon': {
|
|
407
|
+
const closed = geometry.closed !== false;
|
|
408
|
+
annot = {
|
|
409
|
+
subtype: closed ? 'Polygon' : 'PolyLine',
|
|
410
|
+
color,
|
|
411
|
+
fill: closed ? style.fill : undefined,
|
|
412
|
+
width,
|
|
413
|
+
alpha,
|
|
414
|
+
dash,
|
|
415
|
+
vertices: pts,
|
|
416
|
+
startArrow: !closed && style.startCap === 'arrow',
|
|
417
|
+
endArrow: !closed && style.cap === 'arrow',
|
|
418
|
+
};
|
|
419
|
+
break;
|
|
420
|
+
}
|
|
421
|
+
case 'text':
|
|
422
|
+
annot = {
|
|
423
|
+
subtype: 'FreeText',
|
|
424
|
+
color,
|
|
425
|
+
fontSize: style.fontSize ?? DEFAULT_TEXT_FONT_SIZE,
|
|
426
|
+
text: shape.text ?? '',
|
|
427
|
+
alpha,
|
|
428
|
+
};
|
|
429
|
+
break;
|
|
430
|
+
default:
|
|
431
|
+
return null;
|
|
432
|
+
}
|
|
433
|
+
return { id: shape.id, ops, bounds, annot };
|
|
434
|
+
};
|
|
435
|
+
/** The measurement annotation's line / rectangle (not its tile). */
|
|
436
|
+
export const measurementMark = (placed, ctx) => {
|
|
437
|
+
const bounds = measurementMarkBounds(placed);
|
|
438
|
+
if (!bounds)
|
|
439
|
+
return null;
|
|
440
|
+
const ops = measurementMarkOps(placed, ctx);
|
|
441
|
+
const color = placed.lineColor ?? MEASUREMENT_LINE_COLOR;
|
|
442
|
+
const alpha = parseHexColor(color).alpha;
|
|
443
|
+
const dash = !!placed.lineDash;
|
|
444
|
+
if (placementOf(placed) === 'rectangle' && placed.rect) {
|
|
445
|
+
const n = normalizeRect(placed.rect);
|
|
446
|
+
return {
|
|
447
|
+
id: `${placed.id}:rect`,
|
|
448
|
+
ops,
|
|
449
|
+
bounds,
|
|
450
|
+
annot: {
|
|
451
|
+
subtype: 'Square',
|
|
452
|
+
color,
|
|
453
|
+
width: placed.lineWidth ?? MEASUREMENT_RECT_WIDTH,
|
|
454
|
+
alpha,
|
|
455
|
+
dash,
|
|
456
|
+
rect: boundsToRect(n),
|
|
457
|
+
},
|
|
458
|
+
};
|
|
459
|
+
}
|
|
460
|
+
if (placementOf(placed) === 'line' && placed.line) {
|
|
461
|
+
return {
|
|
462
|
+
id: `${placed.id}:line`,
|
|
463
|
+
ops,
|
|
464
|
+
bounds,
|
|
465
|
+
annot: {
|
|
466
|
+
subtype: 'Line',
|
|
467
|
+
color,
|
|
468
|
+
width: placed.lineWidth ?? MEASUREMENT_LINE_WIDTH,
|
|
469
|
+
alpha,
|
|
470
|
+
dash,
|
|
471
|
+
a: placed.line.a,
|
|
472
|
+
b: placed.line.b,
|
|
473
|
+
startArrow: placed.lineStartCap === 'arrow',
|
|
474
|
+
endArrow: placed.lineCap === 'arrow',
|
|
475
|
+
},
|
|
476
|
+
};
|
|
477
|
+
}
|
|
478
|
+
return null;
|
|
479
|
+
};
|
|
@@ -39,6 +39,8 @@ export declare const applyMatrix: (m: AffineMatrix, x: number, y: number) => {
|
|
|
39
39
|
x: number;
|
|
40
40
|
y: number;
|
|
41
41
|
};
|
|
42
|
+
/** The overlap of two rects, or null when they do not overlap. */
|
|
43
|
+
export declare const intersectRects: (a: DocRect, b: DocRect) => DocRect | null;
|
|
42
44
|
export declare const rectsIntersect: (a: DocRect, b: DocRect) => boolean;
|
|
43
45
|
/** Axis-aligned bounds → DocRect, inflated by `pad` on every side. */
|
|
44
46
|
export declare const boundsToRect: (b: {
|
|
@@ -54,6 +54,16 @@ export const applyMatrix = (m, x, y) => ({
|
|
|
54
54
|
x: m[0] * x + m[2] * y + m[4],
|
|
55
55
|
y: m[1] * x + m[3] * y + m[5],
|
|
56
56
|
});
|
|
57
|
+
/** The overlap of two rects, or null when they do not overlap. */
|
|
58
|
+
export const intersectRects = (a, b) => {
|
|
59
|
+
const x = Math.max(a.x, b.x);
|
|
60
|
+
const y = Math.max(a.y, b.y);
|
|
61
|
+
const right = Math.min(a.x + a.width, b.x + b.width);
|
|
62
|
+
const bottom = Math.min(a.y + a.height, b.y + b.height);
|
|
63
|
+
if (right <= x || bottom <= y)
|
|
64
|
+
return null;
|
|
65
|
+
return { x, y, width: right - x, height: bottom - y };
|
|
66
|
+
};
|
|
57
67
|
export const rectsIntersect = (a, b) => a.x < b.x + b.width &&
|
|
58
68
|
a.x + a.width > b.x &&
|
|
59
69
|
a.y < b.y + b.height &&
|
|
@@ -1,2 +1,10 @@
|
|
|
1
|
-
import { type RenderCanvasToPdfInput, type RenderCanvasToPdfResult } from './types.js';
|
|
1
|
+
import { type RenderCanvasToPdfInput, type RenderCanvasToPdfResult, type RenderPdfCanvasToPdfInput } from './types.js';
|
|
2
2
|
export declare const renderCanvasToPdf: (input: RenderCanvasToPdfInput) => Promise<RenderCanvasToPdfResult>;
|
|
3
|
+
/**
|
|
4
|
+
* Export a PdfCanvas file. Each page's state is drawn in that page's own doc
|
|
5
|
+
* space (the DISPLAYED page: rotated extents, origin top-left). A user
|
|
6
|
+
* rotation is written into the page's /Rotate — so the recipient sees the
|
|
7
|
+
* page as the user did — and the page matrix undoes the combined rotation.
|
|
8
|
+
* Pages without a state are still rotated.
|
|
9
|
+
*/
|
|
10
|
+
export declare const renderPdfCanvasToPdf: (input: RenderPdfCanvasToPdfInput) => Promise<RenderCanvasToPdfResult>;
|