@segnavia/format 0.38.0 → 0.40.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/board-edit.d.ts +2 -1
- package/dist/board-geometry.d.ts +2 -1
- package/dist/board-section-grid.d.ts +2 -1
- package/dist/board-sections.d.ts +2 -1
- package/dist/board.d.ts +8 -8
- package/dist/board.js +15 -11
- package/dist/book-exports.d.ts +2 -2
- package/dist/book-section.d.ts +171 -0
- package/dist/book-section.js +13 -2
- package/dist/book.d.ts +189 -47
- package/dist/book.js +18 -2
- package/dist/cover.d.ts +500 -0
- package/dist/cover.js +100 -0
- package/dist/deck-from-slides.d.ts +23 -4
- package/dist/deck.d.ts +144 -42
- package/dist/deck.js +22 -24
- package/dist/direction.d.ts +1 -1
- package/dist/font-collection.d.ts +8 -0
- package/dist/font-collection.js +191 -0
- package/dist/font-face.d.ts +8 -0
- package/dist/font-face.js +24 -0
- package/dist/font-refusal.d.ts +5 -0
- package/dist/font-refusal.js +9 -0
- package/dist/font-signature.d.ts +5 -0
- package/dist/font-signature.js +13 -0
- package/dist/fonts.d.ts +6 -1
- package/dist/fonts.js +3 -1
- package/dist/geometry.d.ts +20 -0
- package/dist/geometry.js +18 -0
- package/dist/image-fit.d.ts +10 -0
- package/dist/image-fit.js +10 -0
- package/dist/imposition-marks.d.ts +1 -1
- package/dist/imposition-schema.d.ts +185 -0
- package/dist/imposition-schema.js +122 -0
- package/dist/imposition.d.ts +8 -6
- package/dist/imposition.js +53 -42
- package/dist/index.d.ts +23 -1756
- package/dist/index.js +29 -212
- package/dist/json-schemas.d.ts +2181 -0
- package/dist/json-schemas.js +43 -0
- package/dist/media.d.ts +152 -0
- package/dist/media.js +119 -0
- package/dist/note-series.d.ts +4 -4
- package/dist/note-series.js +0 -5
- package/dist/page.d.ts +359 -0
- package/dist/page.js +110 -0
- package/dist/paper.d.ts +5 -5
- package/dist/placement-cycle.d.ts +5 -0
- package/dist/placement-cycle.js +30 -0
- package/dist/placement-refusal.d.ts +5 -0
- package/dist/placement-refusal.js +6 -0
- package/dist/placement.d.ts +76 -0
- package/dist/placement.js +100 -0
- package/dist/print.d.ts +72 -0
- package/dist/print.js +38 -0
- package/dist/printed-page-imposition.d.ts +2 -1
- package/dist/shots-used.d.ts +0 -1
- package/dist/shots-used.js +2 -2
- package/dist/slots.d.ts +13 -13
- package/package.json +1 -1
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
//#region src/font-signature.ts
|
|
2
|
+
const COLLECTION_TAG = "ttcf";
|
|
3
|
+
function classifyFont(bytes, offset = 0) {
|
|
4
|
+
if (!Number.isSafeInteger(offset) || offset < 0 || offset > bytes.length - 4) return;
|
|
5
|
+
const tag = String.fromCharCode(bytes[offset] ?? 0, bytes[offset + 1] ?? 0, bytes[offset + 2] ?? 0, bytes[offset + 3] ?? 0);
|
|
6
|
+
if (tag === "wOF2") return "woff2";
|
|
7
|
+
if (tag === "wOFF") return "woff";
|
|
8
|
+
if (tag === "OTTO") return "opentype";
|
|
9
|
+
if (tag === "ttcf") return "collection";
|
|
10
|
+
if (tag === "true" || tag === "\0\0\0") return "truetype";
|
|
11
|
+
}
|
|
12
|
+
//#endregion
|
|
13
|
+
export { COLLECTION_TAG, classifyFont };
|
package/dist/fonts.d.ts
CHANGED
|
@@ -20,7 +20,7 @@ export declare function localFontReferences(references: readonly FontReference[]
|
|
|
20
20
|
local: string;
|
|
21
21
|
fallback: string;
|
|
22
22
|
}>;
|
|
23
|
-
export declare const FONT_FORMATS: readonly ["woff2", "woff", "truetype", "opentype"];
|
|
23
|
+
export declare const FONT_FORMATS: readonly ["woff2", "woff", "truetype", "opentype", "collection"];
|
|
24
24
|
export type FontFormat = (typeof FONT_FORMATS)[number];
|
|
25
25
|
export declare const LocalFaceTransport: z.ZodObject<{
|
|
26
26
|
family: z.ZodString;
|
|
@@ -29,12 +29,14 @@ export declare const LocalFaceTransport: z.ZodObject<{
|
|
|
29
29
|
woff: "woff";
|
|
30
30
|
truetype: "truetype";
|
|
31
31
|
opentype: "opentype";
|
|
32
|
+
collection: "collection";
|
|
32
33
|
}>;
|
|
33
34
|
weight: z.ZodOptional<z.ZodUnion<readonly [z.ZodNumber, z.ZodString]>>;
|
|
34
35
|
style: z.ZodOptional<z.ZodEnum<{
|
|
35
36
|
normal: "normal";
|
|
36
37
|
italic: "italic";
|
|
37
38
|
}>>;
|
|
39
|
+
postscriptName: z.ZodOptional<z.ZodString>;
|
|
38
40
|
data: z.ZodString;
|
|
39
41
|
}, z.core.$strict>;
|
|
40
42
|
export type LocalFaceTransport = z.infer<typeof LocalFaceTransport>;
|
|
@@ -45,12 +47,14 @@ export declare const LocalFacesTransport: z.ZodArray<z.ZodObject<{
|
|
|
45
47
|
woff: "woff";
|
|
46
48
|
truetype: "truetype";
|
|
47
49
|
opentype: "opentype";
|
|
50
|
+
collection: "collection";
|
|
48
51
|
}>;
|
|
49
52
|
weight: z.ZodOptional<z.ZodUnion<readonly [z.ZodNumber, z.ZodString]>>;
|
|
50
53
|
style: z.ZodOptional<z.ZodEnum<{
|
|
51
54
|
normal: "normal";
|
|
52
55
|
italic: "italic";
|
|
53
56
|
}>>;
|
|
57
|
+
postscriptName: z.ZodOptional<z.ZodString>;
|
|
54
58
|
data: z.ZodString;
|
|
55
59
|
}, z.core.$strict>>;
|
|
56
60
|
export type LocalFacesInput = LocalFaceTransport[];
|
|
@@ -63,6 +67,7 @@ export interface FontFace {
|
|
|
63
67
|
weight?: number | string;
|
|
64
68
|
style?: 'normal' | 'italic';
|
|
65
69
|
unicodeRange?: string;
|
|
70
|
+
postscriptName?: string;
|
|
66
71
|
}
|
|
67
72
|
export interface AppFont {
|
|
68
73
|
family: string;
|
package/dist/fonts.js
CHANGED
|
@@ -26,13 +26,15 @@ const FONT_FORMATS = [
|
|
|
26
26
|
"woff2",
|
|
27
27
|
"woff",
|
|
28
28
|
"truetype",
|
|
29
|
-
"opentype"
|
|
29
|
+
"opentype",
|
|
30
|
+
"collection"
|
|
30
31
|
];
|
|
31
32
|
const LocalFaceTransportShape = {
|
|
32
33
|
family: z.string().min(1),
|
|
33
34
|
format: z.enum(FONT_FORMATS),
|
|
34
35
|
weight: z.union([z.number(), z.string()]).optional(),
|
|
35
36
|
style: z.enum(["normal", "italic"]).optional(),
|
|
37
|
+
postscriptName: z.string().min(1).optional(),
|
|
36
38
|
data: z.string()
|
|
37
39
|
};
|
|
38
40
|
const LocalFaceTransport = z.strictObject(LocalFaceTransportShape);
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
//#region src/geometry.d.ts
|
|
3
|
+
export declare const Size: z.ZodObject<{
|
|
4
|
+
width: z.ZodNumber;
|
|
5
|
+
height: z.ZodNumber;
|
|
6
|
+
}, z.core.$strip>;
|
|
7
|
+
export type Size = z.infer<typeof Size>;
|
|
8
|
+
export declare const Box: z.ZodObject<{
|
|
9
|
+
x: z.ZodNumber;
|
|
10
|
+
y: z.ZodNumber;
|
|
11
|
+
width: z.ZodNumber;
|
|
12
|
+
height: z.ZodNumber;
|
|
13
|
+
}, z.core.$strip>;
|
|
14
|
+
export type Box = z.infer<typeof Box>;
|
|
15
|
+
export declare const Point: z.ZodObject<{
|
|
16
|
+
x: z.ZodNumber;
|
|
17
|
+
y: z.ZodNumber;
|
|
18
|
+
}, z.core.$strip>;
|
|
19
|
+
export type Point = z.infer<typeof Point>;
|
|
20
|
+
//#endregion
|
package/dist/geometry.js
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
//#region src/geometry.ts
|
|
3
|
+
const Size = z.object({
|
|
4
|
+
width: z.number().int().positive(),
|
|
5
|
+
height: z.number().int().positive()
|
|
6
|
+
});
|
|
7
|
+
const Box = z.object({
|
|
8
|
+
x: z.number(),
|
|
9
|
+
y: z.number(),
|
|
10
|
+
width: z.number(),
|
|
11
|
+
height: z.number()
|
|
12
|
+
});
|
|
13
|
+
const Point = z.object({
|
|
14
|
+
x: z.number(),
|
|
15
|
+
y: z.number()
|
|
16
|
+
});
|
|
17
|
+
//#endregion
|
|
18
|
+
export { Box, Point, Size };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { MarkSegment } from "./paper.js";
|
|
2
|
-
import { Imposition } from "./
|
|
2
|
+
import { Imposition } from "./imposition-schema.js";
|
|
3
3
|
//#region src/imposition-marks.d.ts
|
|
4
4
|
export declare const MIN_MARK_LENGTH_MM = 2;
|
|
5
5
|
export type ImpositionMarkEdge = 'top' | 'right' | 'bottom' | 'left';
|
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
//#region src/imposition-schema.d.ts
|
|
3
|
+
export declare const MAX_IMPOSITION_CELLS = 10000;
|
|
4
|
+
export declare const Imposition: z.ZodPipe<z.ZodObject<{
|
|
5
|
+
paper: z.ZodUnion<readonly [z.ZodEnum<{
|
|
6
|
+
letter: "letter";
|
|
7
|
+
legal: "legal";
|
|
8
|
+
tabloid: "tabloid";
|
|
9
|
+
a3: "a3";
|
|
10
|
+
a4: "a4";
|
|
11
|
+
a5: "a5";
|
|
12
|
+
"business-card-us": "business-card-us";
|
|
13
|
+
"business-card-eu": "business-card-eu";
|
|
14
|
+
"business-card-square-us": "business-card-square-us";
|
|
15
|
+
"business-card-slim-us": "business-card-slim-us";
|
|
16
|
+
"postcard-4x6": "postcard-4x6";
|
|
17
|
+
"postcard-5x7": "postcard-5x7";
|
|
18
|
+
"postcard-6x9": "postcard-6x9";
|
|
19
|
+
"postcard-6x11": "postcard-6x11";
|
|
20
|
+
"card-square-4in": "card-square-4in";
|
|
21
|
+
"half-letter": "half-letter";
|
|
22
|
+
a6: "a6";
|
|
23
|
+
dl: "dl";
|
|
24
|
+
"rack-card-4x9": "rack-card-4x9";
|
|
25
|
+
"rack-card-3.5x8.5": "rack-card-3.5x8.5";
|
|
26
|
+
"poster-12x18": "poster-12x18";
|
|
27
|
+
"poster-16x20": "poster-16x20";
|
|
28
|
+
"poster-18x24": "poster-18x24";
|
|
29
|
+
"poster-24x36": "poster-24x36";
|
|
30
|
+
a2: "a2";
|
|
31
|
+
a1: "a1";
|
|
32
|
+
a0: "a0";
|
|
33
|
+
}>, z.ZodObject<{
|
|
34
|
+
width: z.ZodNumber;
|
|
35
|
+
height: z.ZodNumber;
|
|
36
|
+
unit: z.ZodEnum<{
|
|
37
|
+
in: "in";
|
|
38
|
+
mm: "mm";
|
|
39
|
+
pt: "pt";
|
|
40
|
+
}>;
|
|
41
|
+
}, z.core.$strip>]>;
|
|
42
|
+
orientation: z.ZodDefault<z.ZodEnum<{
|
|
43
|
+
portrait: "portrait";
|
|
44
|
+
landscape: "landscape";
|
|
45
|
+
}>>;
|
|
46
|
+
unit: z.ZodDefault<z.ZodEnum<{
|
|
47
|
+
in: "in";
|
|
48
|
+
mm: "mm";
|
|
49
|
+
pt: "pt";
|
|
50
|
+
}>>;
|
|
51
|
+
margin: z.ZodDefault<z.ZodObject<{
|
|
52
|
+
top: z.ZodDefault<z.ZodNumber>;
|
|
53
|
+
right: z.ZodDefault<z.ZodNumber>;
|
|
54
|
+
bottom: z.ZodDefault<z.ZodNumber>;
|
|
55
|
+
left: z.ZodDefault<z.ZodNumber>;
|
|
56
|
+
}, z.core.$strip>>;
|
|
57
|
+
columns: z.ZodOptional<z.ZodNumber>;
|
|
58
|
+
rows: z.ZodOptional<z.ZodNumber>;
|
|
59
|
+
cell: z.ZodObject<{
|
|
60
|
+
width: z.ZodOptional<z.ZodNumber>;
|
|
61
|
+
height: z.ZodNumber;
|
|
62
|
+
}, z.core.$strip>;
|
|
63
|
+
gap: z.ZodDefault<z.ZodObject<{
|
|
64
|
+
column: z.ZodDefault<z.ZodNumber>;
|
|
65
|
+
row: z.ZodDefault<z.ZodNumber>;
|
|
66
|
+
}, z.core.$strip>>;
|
|
67
|
+
bleed: z.ZodDefault<z.ZodNumber>;
|
|
68
|
+
safe: z.ZodDefault<z.ZodNumber>;
|
|
69
|
+
fit: z.ZodDefault<z.ZodEnum<{
|
|
70
|
+
contain: "contain";
|
|
71
|
+
cover: "cover";
|
|
72
|
+
}>>;
|
|
73
|
+
fill: z.ZodDefault<z.ZodEnum<{
|
|
74
|
+
sequence: "sequence";
|
|
75
|
+
repeat: "repeat";
|
|
76
|
+
}>>;
|
|
77
|
+
sides: z.ZodOptional<z.ZodEnum<{
|
|
78
|
+
one: "one";
|
|
79
|
+
two: "two";
|
|
80
|
+
}>>;
|
|
81
|
+
flip: z.ZodDefault<z.ZodEnum<{
|
|
82
|
+
long: "long";
|
|
83
|
+
short: "short";
|
|
84
|
+
}>>;
|
|
85
|
+
skip: z.ZodDefault<z.ZodNumber>;
|
|
86
|
+
dir: z.ZodDefault<z.ZodEnum<{
|
|
87
|
+
ltr: "ltr";
|
|
88
|
+
rtl: "rtl";
|
|
89
|
+
}>>;
|
|
90
|
+
marks: z.ZodDefault<z.ZodBoolean>;
|
|
91
|
+
markColor: z.ZodDefault<z.ZodEnum<{
|
|
92
|
+
black: "black";
|
|
93
|
+
registration: "registration";
|
|
94
|
+
}>>;
|
|
95
|
+
cornerMarks: z.ZodDefault<z.ZodBoolean>;
|
|
96
|
+
fold: z.ZodOptional<z.ZodEnum<{
|
|
97
|
+
custom: "custom";
|
|
98
|
+
letter: "letter";
|
|
99
|
+
half: "half";
|
|
100
|
+
z: "z";
|
|
101
|
+
gate: "gate";
|
|
102
|
+
}>>;
|
|
103
|
+
panels: z.ZodOptional<z.ZodArray<z.ZodNumber>>;
|
|
104
|
+
}, z.core.$strip>, z.ZodTransform<{
|
|
105
|
+
paper: "letter" | "legal" | "tabloid" | "a3" | "a4" | "a5" | "business-card-us" | "business-card-eu" | "business-card-square-us" | "business-card-slim-us" | "postcard-4x6" | "postcard-5x7" | "postcard-6x9" | "postcard-6x11" | "card-square-4in" | "half-letter" | "a6" | "dl" | "rack-card-4x9" | "rack-card-3.5x8.5" | "poster-12x18" | "poster-16x20" | "poster-18x24" | "poster-24x36" | "a2" | "a1" | "a0" | {
|
|
106
|
+
width: number;
|
|
107
|
+
height: number;
|
|
108
|
+
unit: "in" | "mm" | "pt";
|
|
109
|
+
};
|
|
110
|
+
orientation: "portrait" | "landscape";
|
|
111
|
+
unit: "in" | "mm" | "pt";
|
|
112
|
+
margin: {
|
|
113
|
+
top: number;
|
|
114
|
+
right: number;
|
|
115
|
+
bottom: number;
|
|
116
|
+
left: number;
|
|
117
|
+
};
|
|
118
|
+
cell: {
|
|
119
|
+
height: number;
|
|
120
|
+
width?: number | undefined;
|
|
121
|
+
};
|
|
122
|
+
gap: {
|
|
123
|
+
column: number;
|
|
124
|
+
row: number;
|
|
125
|
+
};
|
|
126
|
+
bleed: number;
|
|
127
|
+
safe: number;
|
|
128
|
+
fit: "contain" | "cover";
|
|
129
|
+
fill: "sequence" | "repeat";
|
|
130
|
+
flip: "long" | "short";
|
|
131
|
+
skip: number;
|
|
132
|
+
dir: "ltr" | "rtl";
|
|
133
|
+
marks: boolean;
|
|
134
|
+
markColor: "black" | "registration";
|
|
135
|
+
cornerMarks: boolean;
|
|
136
|
+
columns?: number | undefined;
|
|
137
|
+
rows?: number | undefined;
|
|
138
|
+
sides?: "one" | "two" | undefined;
|
|
139
|
+
fold?: "custom" | "letter" | "half" | "z" | "gate" | undefined;
|
|
140
|
+
panels?: number[] | undefined;
|
|
141
|
+
} & {
|
|
142
|
+
columns: number;
|
|
143
|
+
rows: number;
|
|
144
|
+
sides: "one" | "two";
|
|
145
|
+
}, {
|
|
146
|
+
paper: "letter" | "legal" | "tabloid" | "a3" | "a4" | "a5" | "business-card-us" | "business-card-eu" | "business-card-square-us" | "business-card-slim-us" | "postcard-4x6" | "postcard-5x7" | "postcard-6x9" | "postcard-6x11" | "card-square-4in" | "half-letter" | "a6" | "dl" | "rack-card-4x9" | "rack-card-3.5x8.5" | "poster-12x18" | "poster-16x20" | "poster-18x24" | "poster-24x36" | "a2" | "a1" | "a0" | {
|
|
147
|
+
width: number;
|
|
148
|
+
height: number;
|
|
149
|
+
unit: "in" | "mm" | "pt";
|
|
150
|
+
};
|
|
151
|
+
orientation: "portrait" | "landscape";
|
|
152
|
+
unit: "in" | "mm" | "pt";
|
|
153
|
+
margin: {
|
|
154
|
+
top: number;
|
|
155
|
+
right: number;
|
|
156
|
+
bottom: number;
|
|
157
|
+
left: number;
|
|
158
|
+
};
|
|
159
|
+
cell: {
|
|
160
|
+
height: number;
|
|
161
|
+
width?: number | undefined;
|
|
162
|
+
};
|
|
163
|
+
gap: {
|
|
164
|
+
column: number;
|
|
165
|
+
row: number;
|
|
166
|
+
};
|
|
167
|
+
bleed: number;
|
|
168
|
+
safe: number;
|
|
169
|
+
fit: "contain" | "cover";
|
|
170
|
+
fill: "sequence" | "repeat";
|
|
171
|
+
flip: "long" | "short";
|
|
172
|
+
skip: number;
|
|
173
|
+
dir: "ltr" | "rtl";
|
|
174
|
+
marks: boolean;
|
|
175
|
+
markColor: "black" | "registration";
|
|
176
|
+
cornerMarks: boolean;
|
|
177
|
+
columns?: number | undefined;
|
|
178
|
+
rows?: number | undefined;
|
|
179
|
+
sides?: "one" | "two" | undefined;
|
|
180
|
+
fold?: "custom" | "letter" | "half" | "z" | "gate" | undefined;
|
|
181
|
+
panels?: number[] | undefined;
|
|
182
|
+
}>>;
|
|
183
|
+
export type Imposition = z.infer<typeof Imposition>;
|
|
184
|
+
export type ImpositionInput = z.input<typeof Imposition>;
|
|
185
|
+
//#endregion
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
import { Orientation, Paper, PaperUnit, sheetMm, toMillimeters } from "./paper.js";
|
|
2
|
+
import { Margin, MarkColor } from "./print.js";
|
|
3
|
+
import { refuseOverflow, refuseSafe } from "./imposition-fit.js";
|
|
4
|
+
import { FOLD_KINDS, refineFold, resolveImposition } from "./fold.js";
|
|
5
|
+
import { z } from "zod";
|
|
6
|
+
//#region src/imposition-schema.ts
|
|
7
|
+
const ImpositionGap = z.object({
|
|
8
|
+
column: z.number().nonnegative().default(0),
|
|
9
|
+
row: z.number().nonnegative().default(0)
|
|
10
|
+
});
|
|
11
|
+
const MAX_IMPOSITION_CELLS = 1e4;
|
|
12
|
+
const Imposition = z.object({
|
|
13
|
+
paper: Paper,
|
|
14
|
+
orientation: Orientation.default("portrait"),
|
|
15
|
+
unit: PaperUnit.default("mm"),
|
|
16
|
+
margin: Margin.default({
|
|
17
|
+
top: 0,
|
|
18
|
+
right: 0,
|
|
19
|
+
bottom: 0,
|
|
20
|
+
left: 0
|
|
21
|
+
}),
|
|
22
|
+
columns: z.number().int().positive().optional(),
|
|
23
|
+
rows: z.number().int().positive().optional(),
|
|
24
|
+
cell: z.object({
|
|
25
|
+
width: z.number().positive().optional(),
|
|
26
|
+
height: z.number().positive()
|
|
27
|
+
}),
|
|
28
|
+
gap: ImpositionGap.default({
|
|
29
|
+
column: 0,
|
|
30
|
+
row: 0
|
|
31
|
+
}),
|
|
32
|
+
bleed: z.number().nonnegative().default(0),
|
|
33
|
+
safe: z.number().nonnegative().default(0),
|
|
34
|
+
fit: z.enum(["contain", "cover"]).default("contain"),
|
|
35
|
+
fill: z.enum(["sequence", "repeat"]).default("sequence"),
|
|
36
|
+
sides: z.enum(["one", "two"]).optional(),
|
|
37
|
+
flip: z.enum(["long", "short"]).default("long"),
|
|
38
|
+
skip: z.number().int().nonnegative().default(0),
|
|
39
|
+
dir: z.enum(["ltr", "rtl"]).default("ltr"),
|
|
40
|
+
marks: z.boolean().default(false),
|
|
41
|
+
markColor: MarkColor.default("black"),
|
|
42
|
+
cornerMarks: z.boolean().default(false),
|
|
43
|
+
fold: z.enum(FOLD_KINDS).optional(),
|
|
44
|
+
panels: z.array(z.number().positive()).optional()
|
|
45
|
+
}).superRefine((imposition, ctx) => {
|
|
46
|
+
if (imposition.markColor === "registration" && !imposition.marks) ctx.addIssue({
|
|
47
|
+
code: "custom",
|
|
48
|
+
path: ["markColor"],
|
|
49
|
+
message: "markColor requires marks to be true"
|
|
50
|
+
});
|
|
51
|
+
if (imposition.cornerMarks && !imposition.marks) ctx.addIssue({
|
|
52
|
+
code: "custom",
|
|
53
|
+
path: ["cornerMarks"],
|
|
54
|
+
message: "cornerMarks requires marks to be true"
|
|
55
|
+
});
|
|
56
|
+
if (imposition.panels !== void 0 && !imposition.fold) ctx.addIssue({
|
|
57
|
+
code: "custom",
|
|
58
|
+
path: ["panels"],
|
|
59
|
+
message: "panels needs fold; set fold or remove panels"
|
|
60
|
+
});
|
|
61
|
+
if (imposition.fold) {
|
|
62
|
+
const panelCount = imposition.panels?.length ?? 0;
|
|
63
|
+
if (panelCount > 1e4) {
|
|
64
|
+
ctx.addIssue({
|
|
65
|
+
code: "custom",
|
|
66
|
+
path: ["panels"],
|
|
67
|
+
message: `the fold has ${panelCount} panels and the ceiling is ${MAX_IMPOSITION_CELLS}; fewer panels clears this refusal`
|
|
68
|
+
});
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
refineFold(imposition, ctx);
|
|
72
|
+
return;
|
|
73
|
+
}
|
|
74
|
+
if (imposition.columns === void 0) ctx.addIssue({
|
|
75
|
+
code: "custom",
|
|
76
|
+
path: ["columns"],
|
|
77
|
+
message: "columns is required; give a column count to clear this refusal"
|
|
78
|
+
});
|
|
79
|
+
if (imposition.rows === void 0) ctx.addIssue({
|
|
80
|
+
code: "custom",
|
|
81
|
+
path: ["rows"],
|
|
82
|
+
message: "rows is required; give a row count to clear this refusal"
|
|
83
|
+
});
|
|
84
|
+
if (imposition.cell.width === void 0) ctx.addIssue({
|
|
85
|
+
code: "custom",
|
|
86
|
+
path: ["cell", "width"],
|
|
87
|
+
message: "cell.width is required; give a cell width to clear this refusal"
|
|
88
|
+
});
|
|
89
|
+
if (imposition.columns === void 0 || imposition.rows === void 0 || imposition.cell.width === void 0) return;
|
|
90
|
+
const cellCount = BigInt(imposition.columns) * BigInt(imposition.rows);
|
|
91
|
+
if (imposition.columns > 1e4 || imposition.rows > 1e4 || cellCount > BigInt(1e4)) {
|
|
92
|
+
ctx.addIssue({
|
|
93
|
+
code: "custom",
|
|
94
|
+
path: ["columns"],
|
|
95
|
+
message: `the grid has ${cellCount} cells and the ceiling is ${MAX_IMPOSITION_CELLS}; fewer columns or rows clears this refusal`
|
|
96
|
+
});
|
|
97
|
+
return;
|
|
98
|
+
}
|
|
99
|
+
const mm = (value) => toMillimeters(value, imposition.unit);
|
|
100
|
+
const paper = sheetMm({
|
|
101
|
+
paper: imposition.paper,
|
|
102
|
+
orientation: imposition.orientation
|
|
103
|
+
});
|
|
104
|
+
const gridWidth = mm(imposition.margin.left + imposition.columns * imposition.cell.width + (imposition.columns - 1) * imposition.gap.column + imposition.margin.right);
|
|
105
|
+
const gridHeight = mm(imposition.margin.top + imposition.rows * imposition.cell.height + (imposition.rows - 1) * imposition.gap.row + imposition.margin.bottom);
|
|
106
|
+
refuseOverflow(ctx, paper, {
|
|
107
|
+
width: gridWidth,
|
|
108
|
+
height: gridHeight
|
|
109
|
+
});
|
|
110
|
+
refuseSafe(ctx, mm(imposition.safe), {
|
|
111
|
+
width: mm(imposition.cell.width),
|
|
112
|
+
height: mm(imposition.cell.height)
|
|
113
|
+
});
|
|
114
|
+
const cells = imposition.columns * imposition.rows;
|
|
115
|
+
if (imposition.skip >= cells) ctx.addIssue({
|
|
116
|
+
code: "custom",
|
|
117
|
+
path: ["skip"],
|
|
118
|
+
message: `skip is ${imposition.skip}, but the grid has ${cells} cells; skip must be less than ${cells}`
|
|
119
|
+
});
|
|
120
|
+
}).transform(resolveImposition);
|
|
121
|
+
//#endregion
|
|
122
|
+
export { Imposition, MAX_IMPOSITION_CELLS };
|
package/dist/imposition.d.ts
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
|
+
import { Page, PageWidths } from "./page.js";
|
|
2
|
+
import { Print } from "./print.js";
|
|
1
3
|
import { PaperBox } from "./paper.js";
|
|
2
|
-
import { Imposition
|
|
4
|
+
import { Imposition } from "./imposition-schema.js";
|
|
3
5
|
//#region src/imposition.d.ts
|
|
4
6
|
export interface MillimeterEdges {
|
|
5
7
|
top: number;
|
|
@@ -7,7 +9,7 @@ export interface MillimeterEdges {
|
|
|
7
9
|
bottom: number;
|
|
8
10
|
left: number;
|
|
9
11
|
}
|
|
10
|
-
export interface
|
|
12
|
+
export interface ImpositionPlacement {
|
|
11
13
|
page: number;
|
|
12
14
|
paper: number;
|
|
13
15
|
side: 'front' | 'back';
|
|
@@ -26,7 +28,7 @@ export interface Imposed {
|
|
|
26
28
|
};
|
|
27
29
|
papers: number;
|
|
28
30
|
sides: 1 | 2;
|
|
29
|
-
placements:
|
|
31
|
+
placements: ImpositionPlacement[];
|
|
30
32
|
}
|
|
31
33
|
export interface PageFit {
|
|
32
34
|
flow: boolean;
|
|
@@ -52,11 +54,11 @@ export interface PagePlacementLayout {
|
|
|
52
54
|
inset: boolean;
|
|
53
55
|
paper: PaperBox;
|
|
54
56
|
}
|
|
55
|
-
export declare function mirrorPlacement(front:
|
|
57
|
+
export declare function mirrorPlacement(front: ImpositionPlacement, paper: Imposed['paper'], flip: Imposition['flip'], page?: number): ImpositionPlacement;
|
|
56
58
|
export declare function impose(imposition: Imposition, pageCount: number): Imposed;
|
|
57
59
|
export declare function fitPage(page: {
|
|
58
60
|
size: Page['size'];
|
|
59
61
|
print?: Print;
|
|
60
|
-
}, placement:
|
|
61
|
-
export declare function pagePlacementLayout(size: Page['size'], placement:
|
|
62
|
+
}, placement: ImpositionPlacement, fit: 'contain' | 'cover', pageWidths?: PageWidths): PageFit;
|
|
63
|
+
export declare function pagePlacementLayout(size: Page['size'], placement: ImpositionPlacement, fit: PageFit): PagePlacementLayout;
|
|
62
64
|
//#endregion
|
package/dist/imposition.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { PX_PER_MM, roundMillimeters, sheetMm, toMillimeters } from "./paper.js";
|
|
2
|
+
import { resolvePageWidth } from "./page.js";
|
|
2
3
|
import { foldCellPages, foldPageCountMessage } from "./fold.js";
|
|
3
4
|
//#region src/imposition.ts
|
|
4
5
|
const zeroCrop = () => ({
|
|
@@ -225,46 +226,56 @@ function trimDiffers(page, placement) {
|
|
|
225
226
|
const trim = sheetMm(page.print);
|
|
226
227
|
return Math.abs(trim.width - placement.trim.width) > .01 || Math.abs(trim.height - placement.trim.height) > .01;
|
|
227
228
|
}
|
|
228
|
-
function fitPage(page, placement, fit) {
|
|
229
|
+
function fitPage(page, placement, fit, pageWidths) {
|
|
229
230
|
const differs = trimDiffers(page, placement);
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
231
|
+
const size = page.size;
|
|
232
|
+
if (size.height === "auto") {
|
|
233
|
+
const resolved = resolvePageWidth(size, pageWidths);
|
|
234
|
+
if (size.width !== "full") {
|
|
235
|
+
const named = typeof size.width === "string";
|
|
236
|
+
const width = named ? Math.min(resolved.viewportWidth, placement.trim.width * PX_PER_MM) : resolved.viewportWidth;
|
|
237
|
+
const scale = named ? 1 : placement.trim.width * PX_PER_MM / width;
|
|
238
|
+
const inline = named ? (placement.trim.width - width / PX_PER_MM) / 2 : 0;
|
|
239
|
+
return {
|
|
240
|
+
flow: true,
|
|
241
|
+
width,
|
|
242
|
+
height: null,
|
|
243
|
+
scale,
|
|
244
|
+
x: roundMillimeters(placement.trim.x + inline),
|
|
245
|
+
y: placement.trim.y,
|
|
246
|
+
bands: {
|
|
247
|
+
inline: 0,
|
|
248
|
+
block: 0
|
|
249
|
+
},
|
|
250
|
+
crop: zeroCrop(),
|
|
251
|
+
differs
|
|
252
|
+
};
|
|
253
|
+
}
|
|
254
|
+
return {
|
|
255
|
+
flow: true,
|
|
256
|
+
width: placement.bleedBox.width * PX_PER_MM,
|
|
257
|
+
height: null,
|
|
258
|
+
scale: 1,
|
|
259
|
+
x: placement.bleedBox.x,
|
|
260
|
+
y: placement.bleedBox.y,
|
|
261
|
+
bands: {
|
|
262
|
+
inline: 0,
|
|
263
|
+
block: 0
|
|
264
|
+
},
|
|
265
|
+
crop: zeroCrop(),
|
|
266
|
+
differs
|
|
267
|
+
};
|
|
268
|
+
}
|
|
258
269
|
if (fit === "contain") {
|
|
259
|
-
const scale = Math.min(placement.trim.width * PX_PER_MM /
|
|
260
|
-
const width =
|
|
261
|
-
const height =
|
|
270
|
+
const scale = Math.min(placement.trim.width * PX_PER_MM / size.width, placement.trim.height * PX_PER_MM / size.height);
|
|
271
|
+
const width = size.width * scale / PX_PER_MM;
|
|
272
|
+
const height = size.height * scale / PX_PER_MM;
|
|
262
273
|
const inline = (placement.trim.width - width) / 2;
|
|
263
274
|
const block = (placement.trim.height - height) / 2;
|
|
264
275
|
return {
|
|
265
276
|
flow: false,
|
|
266
|
-
width:
|
|
267
|
-
height:
|
|
277
|
+
width: size.width,
|
|
278
|
+
height: size.height,
|
|
268
279
|
scale,
|
|
269
280
|
x: roundMillimeters(placement.trim.x + inline),
|
|
270
281
|
y: roundMillimeters(placement.trim.y + block),
|
|
@@ -278,15 +289,15 @@ function fitPage(page, placement, fit) {
|
|
|
278
289
|
}
|
|
279
290
|
const horizontalBleed = Math.max(placement.bleed.left, placement.bleed.right);
|
|
280
291
|
const verticalBleed = Math.max(placement.bleed.top, placement.bleed.bottom);
|
|
281
|
-
const scale = Math.max((placement.trim.width + horizontalBleed * 2) * PX_PER_MM /
|
|
282
|
-
const width =
|
|
283
|
-
const height =
|
|
292
|
+
const scale = Math.max((placement.trim.width + horizontalBleed * 2) * PX_PER_MM / size.width, (placement.trim.height + verticalBleed * 2) * PX_PER_MM / size.height);
|
|
293
|
+
const width = size.width * scale / PX_PER_MM;
|
|
294
|
+
const height = size.height * scale / PX_PER_MM;
|
|
284
295
|
const x = placement.trim.x + (placement.trim.width - width) / 2;
|
|
285
296
|
const y = placement.trim.y + (placement.trim.height - height) / 2;
|
|
286
297
|
return {
|
|
287
298
|
flow: false,
|
|
288
|
-
width:
|
|
289
|
-
height:
|
|
299
|
+
width: size.width,
|
|
300
|
+
height: size.height,
|
|
290
301
|
scale,
|
|
291
302
|
x: roundMillimeters(x),
|
|
292
303
|
y: roundMillimeters(y),
|
|
@@ -304,7 +315,7 @@ function fitPage(page, placement, fit) {
|
|
|
304
315
|
};
|
|
305
316
|
}
|
|
306
317
|
function pagePlacementLayout(size, placement, fit) {
|
|
307
|
-
if (size === "
|
|
318
|
+
if (size.width === "full") return {
|
|
308
319
|
kind: "fluid",
|
|
309
320
|
piece: {
|
|
310
321
|
width: placement.bleedBox.width * PX_PER_MM,
|
|
@@ -316,14 +327,14 @@ function pagePlacementLayout(size, placement, fit) {
|
|
|
316
327
|
if (size.height === "auto") return {
|
|
317
328
|
kind: "growing",
|
|
318
329
|
piece: {
|
|
319
|
-
width:
|
|
330
|
+
width: fit.width,
|
|
320
331
|
height: placement.trim.height * PX_PER_MM / fit.scale
|
|
321
332
|
},
|
|
322
333
|
inset: false,
|
|
323
334
|
paper: {
|
|
324
335
|
x: fit.x,
|
|
325
336
|
y: fit.y,
|
|
326
|
-
width:
|
|
337
|
+
width: fit.width * fit.scale / PX_PER_MM,
|
|
327
338
|
height: placement.trim.height
|
|
328
339
|
}
|
|
329
340
|
};
|