@segnavia/render 0.6.0 → 0.7.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/book-pdf.js +15 -8
- package/dist/book-render.js +3 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +24 -9
- package/dist/options.d.ts +34 -0
- package/dist/overflow.js +123 -0
- package/dist/page-paper.js +12 -7
- package/dist/pages-pdf.js +7 -4
- package/package.json +4 -4
package/dist/book-pdf.js
CHANGED
|
@@ -5,10 +5,11 @@ import { Book, formatNumber, resolveDirection, sheetMm } from "@segnavia/format"
|
|
|
5
5
|
import { PDFDocument } from "pdf-lib";
|
|
6
6
|
import { bookDocument, bookPrintPart } from "@segnavia/html";
|
|
7
7
|
//#region src/book-pdf.ts
|
|
8
|
-
async function inspect(
|
|
9
|
-
const document = await PDFDocument.load(bytes);
|
|
8
|
+
async function inspect(output) {
|
|
9
|
+
const document = await PDFDocument.load(output.bytes);
|
|
10
10
|
return {
|
|
11
|
-
bytes,
|
|
11
|
+
bytes: output.bytes,
|
|
12
|
+
overflow: output.overflow,
|
|
12
13
|
pages: document.getPageCount(),
|
|
13
14
|
destinations: namedDestinations(document)
|
|
14
15
|
};
|
|
@@ -127,7 +128,7 @@ async function printBody(book, options, adapter) {
|
|
|
127
128
|
targets: true
|
|
128
129
|
});
|
|
129
130
|
if (firstDocument.issues.length > 0) throw new RenderRefusedError(`The book cannot be printed: ${firstDocument.issues.join("; ")}.`);
|
|
130
|
-
let part = await inspect(await adapter.print(firstDocument.html, book, options));
|
|
131
|
+
let part = await inspect(await adapter.print(firstDocument.html, book, options, "body"));
|
|
131
132
|
requireTargets(part, hashTargets(firstDocument));
|
|
132
133
|
const plan = book.rectoOpenings ? planBlanks(firstDocument.sections, part.destinations) : {
|
|
133
134
|
ids: [],
|
|
@@ -139,7 +140,7 @@ async function printBody(book, options, adapter) {
|
|
|
139
140
|
targets: true,
|
|
140
141
|
blankBefore: plan.ids
|
|
141
142
|
});
|
|
142
|
-
part = await inspect(await adapter.print(finalDocument.html, book, options));
|
|
143
|
+
part = await inspect(await adapter.print(finalDocument.html, book, options, "body"));
|
|
143
144
|
requireTargets(part, hashTargets(finalDocument));
|
|
144
145
|
verifyStarts("body", sectionsFor(firstDocument.sections, "body"), plan.predicted, part.destinations);
|
|
145
146
|
}
|
|
@@ -169,7 +170,7 @@ async function printFront(book, source, body, options, adapter) {
|
|
|
169
170
|
crossLinks: true,
|
|
170
171
|
pageNumbers: numbers
|
|
171
172
|
});
|
|
172
|
-
const printed = await inspect(await adapter.print(document.html, book, options));
|
|
173
|
+
const printed = await inspect(await adapter.print(document.html, book, options, "front"));
|
|
173
174
|
if (ids.length === 0) ids.push(...hashTargets(document));
|
|
174
175
|
requireTargets(printed, ids);
|
|
175
176
|
prints.push(printed);
|
|
@@ -219,8 +220,14 @@ async function renderBookPdf(input, options, adapter) {
|
|
|
219
220
|
const bodyBlankPages = new Set(printedBody.blankBefore.map((id) => (printedBody.part.destinations.get(id)?.page ?? 1) - 1));
|
|
220
221
|
const frontBlankPages = new Set(printedFront.trailingBlank ? [front.pages] : []);
|
|
221
222
|
const marginPages = [...marginsFor(book, sectionsFor(printedBody.document.sections, "front"), front.destinations, front.pages, 0, frontBlankPages, book.numbering.frontMatter), ...marginsFor(book, sectionsFor(printedBody.document.sections, "body"), printedBody.part.destinations, printedBody.part.pages, front.pages, bodyBlankPages, book.numbering.body)];
|
|
222
|
-
const
|
|
223
|
-
|
|
223
|
+
const margin = await adapter.print(marginDocument(book, marginPages), book, options, "margin");
|
|
224
|
+
const output = await adapter.finish(await join(front, printedBody.part, margin.bytes), options);
|
|
225
|
+
options.overflow?.report?.({ entries: [
|
|
226
|
+
front.overflow,
|
|
227
|
+
printedBody.part.overflow,
|
|
228
|
+
margin.overflow
|
|
229
|
+
].filter((entry) => entry !== void 0) });
|
|
230
|
+
return output;
|
|
224
231
|
}
|
|
225
232
|
function bookPageCss(book, marginLayer = false) {
|
|
226
233
|
if (!book.page) return "";
|
package/dist/book-render.js
CHANGED
|
@@ -6,9 +6,10 @@ import { frameDocument, newNonce } from "@segnavia/frame/bridge";
|
|
|
6
6
|
//#region src/book-render.ts
|
|
7
7
|
function renderBrowserBookPdf(input, options, dependencies) {
|
|
8
8
|
return renderBookPdf(input, options, {
|
|
9
|
-
print: (html, book, renderOptions,
|
|
9
|
+
print: (html, book, renderOptions, part) => {
|
|
10
10
|
if (!book.page) throw new RenderRefusedError("Printing a continuous book needs page; set page before calling bookPdf.");
|
|
11
11
|
const size = sheetMm(book.page);
|
|
12
|
+
const marginLayer = part === "margin";
|
|
12
13
|
const css = `${bookPageCss(book, marginLayer)}${marginLayer ? marginCss(book) : ""}${dependencies.fontFaces(renderOptions)}${renderOptions.css ?? ""}`;
|
|
13
14
|
return dependencies.render({
|
|
14
15
|
viewport: {
|
|
@@ -39,7 +40,7 @@ function renderBrowserBookPdf(input, options, dependencies) {
|
|
|
39
40
|
bottom: "0mm",
|
|
40
41
|
left: "0mm"
|
|
41
42
|
}
|
|
42
|
-
});
|
|
43
|
+
}, Math.round(size.width * PX_PER_MM), part);
|
|
43
44
|
},
|
|
44
45
|
finish: dependencies.finish
|
|
45
46
|
});
|
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { EffectsReport } from "./effects/types.js";
|
|
2
2
|
import { PressDestination, PressImage, PressReport } from "./press/types.js";
|
|
3
|
-
import { Font, ImageOptions, RenderLimits, RenderOptions } from "./options.js";
|
|
3
|
+
import { Font, ImageOptions, OverflowContribution, OverflowEntry, OverflowPart, OverflowReport, RenderLimits, RenderOptions } from "./options.js";
|
|
4
4
|
import { RenderRefusedError, RendererUnavailableError } from "./errors.js";
|
|
5
5
|
import { BookInput, Deck, ImpositionInput, PageInput } from "@segnavia/format";
|
|
6
6
|
import { PrintOptions } from "@segnavia/frame/print-document";
|
|
@@ -33,4 +33,4 @@ export declare function fontFaces(fonts?: Font[]): string;
|
|
|
33
33
|
export declare function captureImage(tab: Page$1, options: Pick<ImageOptions, 'format' | 'quality' | 'limits'>, fullPage: boolean): Promise<Uint8Array>;
|
|
34
34
|
export declare function openRenderer(options: RendererOptions): Promise<Renderer>;
|
|
35
35
|
//#endregion
|
|
36
|
-
export { type EffectsReport, type Font, type ImageOptions, type PressDestination, type PressImage, type PressReport, type RenderLimits, type RenderOptions, RenderRefusedError, RendererUnavailableError };
|
|
36
|
+
export { type EffectsReport, type Font, type ImageOptions, type OverflowContribution, type OverflowEntry, type OverflowPart, type OverflowReport, type PressDestination, type PressImage, type PressReport, type RenderLimits, type RenderOptions, RenderRefusedError, RendererUnavailableError };
|
package/dist/index.js
CHANGED
|
@@ -5,6 +5,7 @@ import { containFixedPageOverflow } from "./overflow-containment.js";
|
|
|
5
5
|
import { renderDeckPdf } from "./deck-pdf.js";
|
|
6
6
|
import { assertNeutralTolerance } from "./press/color-policy.js";
|
|
7
7
|
import { rewriteEffectsPdf } from "./effects/adapter.js";
|
|
8
|
+
import { measureOverflow, printWithOverflow } from "./overflow.js";
|
|
8
9
|
import { assertPrintOptions, printCss, printPage, printViewport } from "./page-paper.js";
|
|
9
10
|
import { renderPagesPdf } from "./pages-pdf.js";
|
|
10
11
|
import { rewritePressPdf } from "./press/adapter.js";
|
|
@@ -230,10 +231,10 @@ async function openRenderer(options) {
|
|
|
230
231
|
};
|
|
231
232
|
}
|
|
232
233
|
const image = captureImage;
|
|
233
|
-
async function renderPagePdf(page, opts) {
|
|
234
|
+
async function renderPagePdf(page, opts, inputIndex) {
|
|
234
235
|
if (page.print) assertPrintOptions(page.print, opts.preferCssPageSize);
|
|
235
236
|
const viewport = pageViewport(page, void 0, true);
|
|
236
|
-
return
|
|
237
|
+
return withTab({
|
|
237
238
|
viewport,
|
|
238
239
|
scripts: page.scripts === "sandboxed",
|
|
239
240
|
html: pageDocument(page, opts, true),
|
|
@@ -241,15 +242,26 @@ async function openRenderer(options) {
|
|
|
241
242
|
boundMs: opts.boundMs,
|
|
242
243
|
beforeOutput: opts.beforeOutput
|
|
243
244
|
}, async (tab) => {
|
|
244
|
-
if (page.print) return printPage(tab, page.print, opts.preferCssPageSize);
|
|
245
|
+
if (page.print) return printPage(tab, page.print, opts.preferCssPageSize, inputIndex);
|
|
245
246
|
const fixedHeight = typeof page.size === "object" && page.size.height !== "auto" ? page.size.height : null;
|
|
246
247
|
const height = fixedHeight ?? await contentHeight(tab);
|
|
247
|
-
|
|
248
|
+
if (fixedHeight !== null) {
|
|
249
|
+
const overflow = await measureOverflow(tab, viewport.width, "page", inputIndex);
|
|
250
|
+
return {
|
|
251
|
+
bytes: await tab.pdf({
|
|
252
|
+
width: `${viewport.width}px`,
|
|
253
|
+
height: `${height}px`,
|
|
254
|
+
printBackground: true
|
|
255
|
+
}),
|
|
256
|
+
overflow
|
|
257
|
+
};
|
|
258
|
+
}
|
|
259
|
+
return printWithOverflow(tab, viewport.width, "page", {
|
|
248
260
|
width: `${viewport.width}px`,
|
|
249
261
|
height: `${height}px`,
|
|
250
262
|
printBackground: true,
|
|
251
|
-
pageRanges:
|
|
252
|
-
});
|
|
263
|
+
pageRanges: "1"
|
|
264
|
+
}, inputIndex);
|
|
253
265
|
});
|
|
254
266
|
}
|
|
255
267
|
async function renderPiecePdf(page, geometry, css, opts) {
|
|
@@ -286,13 +298,16 @@ async function openRenderer(options) {
|
|
|
286
298
|
return {
|
|
287
299
|
bookPdf(input, opts = {}) {
|
|
288
300
|
return renderBrowserBookPdf(input, opts, {
|
|
289
|
-
render: (setup, pdf) => withTab(setup, (tab) => tab
|
|
301
|
+
render: (setup, pdf, pageWidth, part) => withTab(setup, (tab) => printWithOverflow(tab, pageWidth, part, pdf)),
|
|
290
302
|
fontFaces: (options) => fontFaces(options.fonts),
|
|
291
303
|
finish: finishWithBrowser
|
|
292
304
|
});
|
|
293
305
|
},
|
|
294
306
|
async pagePdf(input, opts = {}) {
|
|
295
|
-
|
|
307
|
+
const printed = await renderPagePdf(Page.parse(input), opts);
|
|
308
|
+
const output = await finishWithBrowser(printed.bytes, opts);
|
|
309
|
+
if (printed.overflow) opts.overflow?.report?.({ entries: [printed.overflow] });
|
|
310
|
+
return output;
|
|
296
311
|
},
|
|
297
312
|
async pageImage(input, opts = {}) {
|
|
298
313
|
const page = Page.parse(input);
|
|
@@ -313,7 +328,7 @@ async function openRenderer(options) {
|
|
|
313
328
|
},
|
|
314
329
|
pagesPdf(inputs, opts = {}) {
|
|
315
330
|
return renderPagesPdf(inputs, opts, {
|
|
316
|
-
pagePdf: renderPagePdf,
|
|
331
|
+
pagePdf: (page, options, inputIndex) => renderPagePdf(page, options, inputIndex),
|
|
317
332
|
piecePdf: renderPiecePdf,
|
|
318
333
|
fontFaces: (options) => fontFaces(options.fonts),
|
|
319
334
|
finish: finishWithBrowser
|
package/dist/options.d.ts
CHANGED
|
@@ -2,6 +2,37 @@ import { EffectsReport } from "./effects/types.js";
|
|
|
2
2
|
import { PressReport } from "./press/types.js";
|
|
3
3
|
import { Page } from "playwright-core";
|
|
4
4
|
//#region src/options.d.ts
|
|
5
|
+
export type OverflowPart = 'page' | 'front' | 'body' | 'margin';
|
|
6
|
+
export interface OverflowContribution {
|
|
7
|
+
/** A short id or tag-and-class path locating the element. */
|
|
8
|
+
locator: string;
|
|
9
|
+
/** Border-box pixels clipped beyond the inline start of the page. */
|
|
10
|
+
clippedStart: number;
|
|
11
|
+
/** Border-box pixels clipped beyond the inline end of the page. */
|
|
12
|
+
clippedEnd: number;
|
|
13
|
+
}
|
|
14
|
+
export interface OverflowEntry {
|
|
15
|
+
/** Output part printed by this entry. */
|
|
16
|
+
part: OverflowPart;
|
|
17
|
+
/** Input position when the public render is pagesPdf. */
|
|
18
|
+
inputIndex?: number;
|
|
19
|
+
/** Printable inline width in CSS pixels. */
|
|
20
|
+
pageWidth: number;
|
|
21
|
+
/** Greatest document scroll width in CSS pixels. */
|
|
22
|
+
extent: number;
|
|
23
|
+
/** Pixels clipped beyond the inline start of the page. */
|
|
24
|
+
clippedStart: number;
|
|
25
|
+
/** Pixels clipped beyond the inline end of the page. */
|
|
26
|
+
clippedEnd: number;
|
|
27
|
+
/** PDF scale used to preserve the print's true size. */
|
|
28
|
+
scale: number;
|
|
29
|
+
/** Up to twenty border boxes that extend beyond the page. */
|
|
30
|
+
elements: OverflowContribution[];
|
|
31
|
+
}
|
|
32
|
+
export interface OverflowReport {
|
|
33
|
+
/** Kept prints in output order. */
|
|
34
|
+
entries: OverflowEntry[];
|
|
35
|
+
}
|
|
5
36
|
export interface Font {
|
|
6
37
|
family: string;
|
|
7
38
|
data: Uint8Array;
|
|
@@ -24,6 +55,9 @@ export interface RenderOptions {
|
|
|
24
55
|
effects?: false | {
|
|
25
56
|
report?: (report: EffectsReport) => void;
|
|
26
57
|
};
|
|
58
|
+
overflow?: {
|
|
59
|
+
report?: (report: OverflowReport) => void;
|
|
60
|
+
};
|
|
27
61
|
press?: {
|
|
28
62
|
profile: Uint8Array;
|
|
29
63
|
neutralTolerance?: number;
|
package/dist/overflow.js
ADDED
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
//#region src/overflow.ts
|
|
2
|
+
/**
|
|
3
|
+
* Chromium's measured maximum print shrink; the 3x overflow demo check fails
|
|
4
|
+
* if it changes. Chromium lays a scaled print out at the narrower width P / s,
|
|
5
|
+
* then shrinks it by at most this factor. The solved scale searches layout
|
|
6
|
+
* widths for the point where rightward content reaches P, and uses this exact
|
|
7
|
+
* cap when it is already reached at the narrowest layout. Rightward generated
|
|
8
|
+
* content in an RTL root is a known limit: neither scroll extent nor element
|
|
9
|
+
* boxes expose it.
|
|
10
|
+
*/
|
|
11
|
+
const CHROMIUM_MAX_SHRINK = 1.5;
|
|
12
|
+
/** Decides the next layout to measure, or the print scale, from measured widths. */
|
|
13
|
+
function solveScale(pageWidth, measurements) {
|
|
14
|
+
const measured = new Map(measurements.map((measurement) => [measurement.layoutWidth, measurement.contentWidth]));
|
|
15
|
+
const atPage = measured.get(pageWidth);
|
|
16
|
+
if (atPage === void 0) return { measure: pageWidth };
|
|
17
|
+
if (atPage <= pageWidth) return { scale: 1 };
|
|
18
|
+
const narrowest = Math.ceil(pageWidth / CHROMIUM_MAX_SHRINK);
|
|
19
|
+
const atNarrowest = measured.get(narrowest);
|
|
20
|
+
if (atNarrowest === void 0) return { measure: narrowest };
|
|
21
|
+
if (atNarrowest >= pageWidth) return { scale: CHROMIUM_MAX_SHRINK };
|
|
22
|
+
let low = narrowest;
|
|
23
|
+
let high = pageWidth;
|
|
24
|
+
let lastSatisfied = pageWidth;
|
|
25
|
+
while (high - low > 1) {
|
|
26
|
+
const middle = Math.floor((low + high) / 2);
|
|
27
|
+
const width = measured.get(middle);
|
|
28
|
+
if (width === void 0) return { measure: middle };
|
|
29
|
+
if (width >= pageWidth) {
|
|
30
|
+
high = middle;
|
|
31
|
+
lastSatisfied = middle;
|
|
32
|
+
} else low = middle;
|
|
33
|
+
}
|
|
34
|
+
return { scale: pageWidth / (measured.get(high) !== void 0 && measured.get(high) >= pageWidth ? high : lastSatisfied) };
|
|
35
|
+
}
|
|
36
|
+
async function measuredOverflow(tab, pageWidth) {
|
|
37
|
+
return tab.evaluate((width) => {
|
|
38
|
+
const root = document.documentElement;
|
|
39
|
+
const extent = Math.max(root.scrollWidth, document.body?.scrollWidth ?? 0);
|
|
40
|
+
const endOverflow = Math.max(0, extent - root.clientWidth);
|
|
41
|
+
const rtl = getComputedStyle(root).direction === "rtl";
|
|
42
|
+
const contributions = [];
|
|
43
|
+
let clippedStart = 0;
|
|
44
|
+
let rightOverflow = rtl ? 0 : endOverflow;
|
|
45
|
+
const locator = (element) => {
|
|
46
|
+
if (element.id) return `#${CSS.escape(element.id)}`;
|
|
47
|
+
const parts = [];
|
|
48
|
+
let current = element;
|
|
49
|
+
while (current && current !== root && parts.length < 3) {
|
|
50
|
+
const classes = [...current.classList].slice(0, 2).map((name) => `.${CSS.escape(name)}`).join("");
|
|
51
|
+
parts.unshift(`${current.localName}${classes}`);
|
|
52
|
+
current = current.parentElement;
|
|
53
|
+
}
|
|
54
|
+
return parts.join(" > ");
|
|
55
|
+
};
|
|
56
|
+
for (const element of document.querySelectorAll("*")) {
|
|
57
|
+
const box = element.getBoundingClientRect();
|
|
58
|
+
const elementStart = Math.max(0, rtl ? box.right - width : -box.left);
|
|
59
|
+
const elementEnd = Math.max(0, rtl ? -box.left : box.right - width);
|
|
60
|
+
clippedStart = Math.max(clippedStart, elementStart);
|
|
61
|
+
rightOverflow = Math.max(rightOverflow, box.right - width);
|
|
62
|
+
if ((elementStart > 0 || elementEnd > 0) && contributions.length < 20) contributions.push({
|
|
63
|
+
locator: locator(element),
|
|
64
|
+
clippedStart: elementStart,
|
|
65
|
+
clippedEnd: elementEnd
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
return {
|
|
69
|
+
overflow: {
|
|
70
|
+
pageWidth: width,
|
|
71
|
+
extent,
|
|
72
|
+
clippedStart,
|
|
73
|
+
clippedEnd: endOverflow,
|
|
74
|
+
elements: contributions
|
|
75
|
+
},
|
|
76
|
+
rightOverflow
|
|
77
|
+
};
|
|
78
|
+
}, pageWidth);
|
|
79
|
+
}
|
|
80
|
+
function overflowEntry(measured, scale, part, inputIndex) {
|
|
81
|
+
return {
|
|
82
|
+
part,
|
|
83
|
+
...inputIndex === void 0 ? {} : { inputIndex },
|
|
84
|
+
...measured.overflow,
|
|
85
|
+
scale
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
async function measureOverflow(tab, pageWidth, part, inputIndex) {
|
|
89
|
+
await tab.emulateMedia({ media: "print" });
|
|
90
|
+
return overflowEntry(await measuredOverflow(tab, pageWidth), 1, part, inputIndex);
|
|
91
|
+
}
|
|
92
|
+
async function printWithOverflow(tab, pageWidth, part, pdf, inputIndex) {
|
|
93
|
+
await tab.emulateMedia({ media: "print" });
|
|
94
|
+
const viewport = tab.viewportSize();
|
|
95
|
+
if (!viewport) throw new Error("The print tab has no viewport.");
|
|
96
|
+
const measurements = [];
|
|
97
|
+
let original;
|
|
98
|
+
let decision = solveScale(pageWidth, measurements);
|
|
99
|
+
while ("measure" in decision) {
|
|
100
|
+
await tab.setViewportSize({
|
|
101
|
+
width: decision.measure,
|
|
102
|
+
height: viewport.height
|
|
103
|
+
});
|
|
104
|
+
const measured = await measuredOverflow(tab, decision.measure);
|
|
105
|
+
if (decision.measure === pageWidth) original = measured;
|
|
106
|
+
measurements.push({
|
|
107
|
+
layoutWidth: decision.measure,
|
|
108
|
+
contentWidth: decision.measure + measured.rightOverflow
|
|
109
|
+
});
|
|
110
|
+
decision = solveScale(pageWidth, measurements);
|
|
111
|
+
}
|
|
112
|
+
await tab.setViewportSize(viewport);
|
|
113
|
+
if (!original) throw new Error("The page-width overflow measurement was not made.");
|
|
114
|
+
return {
|
|
115
|
+
bytes: await tab.pdf({
|
|
116
|
+
...pdf,
|
|
117
|
+
scale: decision.scale
|
|
118
|
+
}),
|
|
119
|
+
overflow: overflowEntry(original, decision.scale, part, inputIndex)
|
|
120
|
+
};
|
|
121
|
+
}
|
|
122
|
+
//#endregion
|
|
123
|
+
export { CHROMIUM_MAX_SHRINK, measureOverflow, printWithOverflow, solveScale };
|
package/dist/page-paper.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { RenderRefusedError } from "./errors.js";
|
|
2
2
|
import { pdfBox, pdfPoint, pt } from "./pdf-geometry.js";
|
|
3
|
+
import { printWithOverflow } from "./overflow.js";
|
|
3
4
|
import { PX_PER_MM, printBoxes, printPadding, printProperties, sheetMm } from "@segnavia/format";
|
|
4
5
|
import { PDFDocument, PDFName, rgb } from "pdf-lib";
|
|
5
6
|
//#region src/page-paper.ts
|
|
@@ -56,11 +57,12 @@ async function addPressBoxes(pdf, print) {
|
|
|
56
57
|
});
|
|
57
58
|
return document.save();
|
|
58
59
|
}
|
|
59
|
-
async function printPage(tab, print, preferCssPageSize) {
|
|
60
|
+
async function printPage(tab, print, preferCssPageSize, inputIndex) {
|
|
60
61
|
if (!usesPressLayout(print)) {
|
|
61
62
|
const mm = sheetMm(print);
|
|
62
63
|
const margin = print.margin;
|
|
63
|
-
|
|
64
|
+
const pageWidth = Math.round(mm.width * PX_PER_MM);
|
|
65
|
+
return printWithOverflow(tab, pageWidth, "page", {
|
|
64
66
|
width: `${mm.width}mm`,
|
|
65
67
|
height: `${mm.height}mm`,
|
|
66
68
|
printBackground: true,
|
|
@@ -71,10 +73,10 @@ async function printPage(tab, print, preferCssPageSize) {
|
|
|
71
73
|
bottom: `${margin.bottom}mm`,
|
|
72
74
|
left: `${margin.left}mm`
|
|
73
75
|
} : void 0
|
|
74
|
-
});
|
|
76
|
+
}, inputIndex);
|
|
75
77
|
}
|
|
76
78
|
const boxes = printBoxes(print);
|
|
77
|
-
const
|
|
79
|
+
const printed = await printWithOverflow(tab, Math.round(boxes.bleedBox.width * PX_PER_MM), "page", {
|
|
78
80
|
width: `${boxes.bleedBox.width}mm`,
|
|
79
81
|
height: `${boxes.bleedBox.height}mm`,
|
|
80
82
|
printBackground: true,
|
|
@@ -85,10 +87,13 @@ async function printPage(tab, print, preferCssPageSize) {
|
|
|
85
87
|
bottom: "0mm",
|
|
86
88
|
left: "0mm"
|
|
87
89
|
}
|
|
88
|
-
});
|
|
89
|
-
const papers = (await PDFDocument.load(
|
|
90
|
+
}, inputIndex);
|
|
91
|
+
const papers = (await PDFDocument.load(printed.bytes)).getPageCount();
|
|
90
92
|
if (papers > 1) throw new RenderRefusedError(`A page with bleed or marks is one printed piece, but the content needs ${papers} papers. Shorten the content, or remove the bleed and marks.`);
|
|
91
|
-
return
|
|
93
|
+
return {
|
|
94
|
+
bytes: await addPressBoxes(printed.bytes, print),
|
|
95
|
+
overflow: printed.overflow
|
|
96
|
+
};
|
|
92
97
|
}
|
|
93
98
|
//#endregion
|
|
94
99
|
export { assertPrintOptions, printCss, printPage, printViewport };
|
package/dist/pages-pdf.js
CHANGED
|
@@ -51,13 +51,16 @@ async function renderPagesPdf(inputs, opts, services) {
|
|
|
51
51
|
if (inputs.length === 0) throw new RenderRefusedError("There is nothing to render. Pass at least one page to clear this refusal.");
|
|
52
52
|
const pages = inputs.map((input) => Page.parse(input));
|
|
53
53
|
if (!opts.imposition) {
|
|
54
|
-
const rendered = await Promise.all(pages.map((page) => services.pagePdf(page, {
|
|
54
|
+
const rendered = await Promise.all(pages.map((page, inputIndex) => services.pagePdf(page, {
|
|
55
55
|
...opts,
|
|
56
56
|
effects: false,
|
|
57
57
|
limits: void 0,
|
|
58
|
-
press: void 0
|
|
59
|
-
|
|
60
|
-
|
|
58
|
+
press: void 0,
|
|
59
|
+
overflow: void 0
|
|
60
|
+
}, inputIndex)));
|
|
61
|
+
const output = await services.finish(await joinPdfs(rendered.map((part) => part.bytes)), opts);
|
|
62
|
+
opts.overflow?.report?.({ entries: rendered.flatMap((part) => part.overflow ? [part.overflow] : []) });
|
|
63
|
+
return output;
|
|
61
64
|
}
|
|
62
65
|
const imposition = Imposition.parse(opts.imposition);
|
|
63
66
|
if (opts.preferCssPageSize) throw new RenderRefusedError("Pages in an imposition take their size from its paper. Remove preferCssPageSize, or remove the imposition, to clear this refusal.");
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@segnavia/render",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.7.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -26,9 +26,9 @@
|
|
|
26
26
|
}
|
|
27
27
|
},
|
|
28
28
|
"dependencies": {
|
|
29
|
-
"@segnavia/format": "0.
|
|
30
|
-
"@segnavia/frame": "0.
|
|
31
|
-
"@segnavia/html": "0.
|
|
29
|
+
"@segnavia/format": "0.7.0",
|
|
30
|
+
"@segnavia/frame": "0.7.0",
|
|
31
|
+
"@segnavia/html": "0.7.0",
|
|
32
32
|
"playwright-core": "1.55.1",
|
|
33
33
|
"pdf-lib": "^1.17.1"
|
|
34
34
|
}
|