reamkit 1.1.0 → 1.3.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/README.md +11 -5
- package/dist/esm/{layout → core}/arc-to-bezier.d.ts +1 -1
- package/dist/esm/{layout → core}/arc-to-bezier.js +2 -2
- package/dist/esm/core/converter/project.js +2 -0
- package/dist/esm/core/converter/ream.js +4 -3
- package/dist/esm/core/document-model/index.d.ts +1 -1
- package/dist/esm/core/document-model/types.d.ts +60 -0
- package/dist/esm/{layout → core/drawingml}/chart-geometry.d.ts +2 -2
- package/dist/esm/{layout → core/drawingml}/chart-geometry.js +79 -117
- package/dist/esm/core/drawingml/chart-parser.d.ts +3 -0
- package/dist/esm/core/drawingml/chart-parser.js +28 -1
- package/dist/esm/{layout → core/drawingml}/preset-geometry.d.ts +2 -2
- package/dist/esm/{layout → core/drawingml}/preset-geometry.js +3 -3
- package/dist/esm/core/drawingml/shape-render.d.ts +8 -0
- package/dist/esm/core/drawingml/shape-render.js +71 -0
- package/dist/esm/core/ir/features.d.ts +1 -0
- package/dist/esm/core/ir/features.js +1 -0
- package/dist/esm/core/ir/flow.d.ts +3 -0
- package/dist/esm/core/links.d.ts +6 -0
- package/dist/esm/core/links.js +19 -0
- package/dist/esm/core/numbering/apply.js +5 -2
- package/dist/esm/core/opc/index.d.ts +1 -0
- package/dist/esm/core/opc/package.js +3 -2
- package/dist/esm/core/opc/relationship-types.d.ts +1 -0
- package/dist/esm/core/opc/relationship-types.js +5 -2
- package/dist/esm/core/style-cascade/index.d.ts +1 -0
- package/dist/esm/core/style-cascade/index.js +1 -0
- package/dist/esm/core/style-cascade/table.d.ts +2 -0
- package/dist/esm/core/style-cascade/table.js +161 -0
- package/dist/esm/core/vector.d.ts +2 -0
- package/dist/esm/core/vector.js +19 -1
- package/dist/esm/excel/print-model.d.ts +3 -0
- package/dist/esm/excel/print-model.js +4 -8
- package/dist/esm/excel/sheet-drawing.d.ts +9 -0
- package/dist/esm/excel/sheet-drawing.js +113 -0
- package/dist/esm/excel/worksheet-parser.d.ts +1 -0
- package/dist/esm/excel/worksheet-parser.js +4 -1
- package/dist/esm/excel/xlsx-reader.js +41 -0
- package/dist/esm/excel/xlsx-to-pdf.js +25 -18
- package/dist/esm/html/html-writer.js +188 -16
- package/dist/esm/index.d.ts +1 -0
- package/dist/esm/layout/page-doc.d.ts +4 -0
- package/dist/esm/layout/styled-layout.d.ts +21 -3
- package/dist/esm/layout/styled-layout.js +745 -259
- package/dist/esm/pdf/encryption.d.ts +34 -0
- package/dist/esm/pdf/encryption.js +143 -0
- package/dist/esm/pdf/index.d.ts +2 -1
- package/dist/esm/pdf/struct-tree.d.ts +7 -1
- package/dist/esm/pdf/struct-tree.js +22 -6
- package/dist/esm/pdf/styled-page-emitter.d.ts +3 -1
- package/dist/esm/pdf/styled-page-emitter.js +185 -35
- package/dist/esm/pdf/styled-page-renderer.d.ts +1 -0
- package/dist/esm/pdf/styled-page-renderer.js +17 -2
- package/dist/esm/pdf/writer.d.ts +2 -0
- package/dist/esm/pdf/writer.js +6 -1
- package/dist/esm/pdf/xmp.d.ts +1 -0
- package/dist/esm/pdf/xmp.js +4 -0
- package/dist/esm/svg/svg-writer.js +2 -6
- package/dist/esm/word/document-parser.d.ts +3 -0
- package/dist/esm/word/document-parser.js +214 -23
- package/dist/esm/word/docx-reader.js +37 -15
- package/dist/esm/word/docx-to-pdf.js +23 -13
- package/dist/esm/word/drawing-parser.d.ts +4 -1
- package/dist/esm/word/drawing-parser.js +53 -2
- package/dist/esm/word/index.d.ts +2 -2
- package/dist/esm/word/styles-parser.js +134 -1
- package/dist/esm/word/table-parser.js +35 -0
- package/package.json +1 -1
|
@@ -11,11 +11,12 @@ import { applyNumbering, applyNumberingToHeadersFooters } from "../core/numberin
|
|
|
11
11
|
import { DEFAULT_RESOLVED_PARAGRAPH, DEFAULT_RESOLVED_RUN } from "../core/style-cascade/types.js";
|
|
12
12
|
import { resolveParagraphProperties, resolveRunProperties } from "../core/style-cascade/resolver.js";
|
|
13
13
|
import "../core/style-cascade/index.js";
|
|
14
|
-
import { PathBuilder } from "../core/vector.js";
|
|
15
|
-
import { arcPoint, arcToBeziers } from "
|
|
16
|
-
import { buildChartScene } from "
|
|
14
|
+
import { PathBuilder, flipTransform } from "../core/vector.js";
|
|
15
|
+
import { arcPoint, arcToBeziers } from "../core/arc-to-bezier.js";
|
|
16
|
+
import { buildChartScene } from "../core/drawingml/chart-geometry.js";
|
|
17
17
|
import { layoutMath, mathGlyphSegments, variantStyle } from "./math-layout.js";
|
|
18
|
-
import {
|
|
18
|
+
import { rectPath } from "../core/drawingml/preset-geometry.js";
|
|
19
|
+
import { buildShapePaths, buildShapeTransform, buildStroke } from "../core/drawingml/shape-render.js";
|
|
19
20
|
import { StructTreeBuilder } from "../pdf/struct-tree.js";
|
|
20
21
|
//#region src/layout/styled-layout.ts
|
|
21
22
|
function parsePdfAProfile(pdfA) {
|
|
@@ -32,23 +33,205 @@ var TWIP_TO_PT = 1 / 20;
|
|
|
32
33
|
var EIGHTH_PT = 1 / 8;
|
|
33
34
|
var DEFAULT_CELL_PADDING_TWIPS = 108;
|
|
34
35
|
var DEFAULT_BORDER_SIZE_EIGHTH = 4;
|
|
36
|
+
var FOOTNOTE_RULE_PT = .75;
|
|
37
|
+
var FOOTNOTE_RULE_GAP_ABOVE = 4;
|
|
38
|
+
var FOOTNOTE_SEPARATOR_HEIGHT = 10;
|
|
39
|
+
var FLOAT_TEXT_GAP = 6;
|
|
40
|
+
var MIN_WRAP_WIDTH = 36;
|
|
41
|
+
function isOutOfFlowFloat(f) {
|
|
42
|
+
return f !== void 0 && f.wrap !== "topAndBottom";
|
|
43
|
+
}
|
|
44
|
+
var FOOTNOTE_RULE_WIDTH = 144;
|
|
45
|
+
function assignNoteNumbers(body) {
|
|
46
|
+
const footnotes = /* @__PURE__ */ new Map();
|
|
47
|
+
const endnotes = /* @__PURE__ */ new Map();
|
|
48
|
+
const paragraphFootnotes = /* @__PURE__ */ new Set();
|
|
49
|
+
const numberRun = (run, n) => ({
|
|
50
|
+
...run,
|
|
51
|
+
text: String(n),
|
|
52
|
+
properties: {
|
|
53
|
+
...run.properties,
|
|
54
|
+
verticalAlign: "superscript"
|
|
55
|
+
}
|
|
56
|
+
});
|
|
57
|
+
const mapParagraph = (paragraph) => {
|
|
58
|
+
if (!paragraph.runs.some((r) => r.footnoteRef !== void 0 || r.endnoteRef !== void 0)) return paragraph;
|
|
59
|
+
return {
|
|
60
|
+
...paragraph,
|
|
61
|
+
runs: paragraph.runs.map((run) => {
|
|
62
|
+
if (run.footnoteRef !== void 0) {
|
|
63
|
+
let n = footnotes.get(run.footnoteRef);
|
|
64
|
+
if (n === void 0) {
|
|
65
|
+
n = footnotes.size + 1;
|
|
66
|
+
footnotes.set(run.footnoteRef, n);
|
|
67
|
+
}
|
|
68
|
+
return numberRun(run, n);
|
|
69
|
+
}
|
|
70
|
+
if (run.endnoteRef !== void 0) {
|
|
71
|
+
let n = endnotes.get(run.endnoteRef);
|
|
72
|
+
if (n === void 0) {
|
|
73
|
+
n = endnotes.size + 1;
|
|
74
|
+
endnotes.set(run.endnoteRef, n);
|
|
75
|
+
}
|
|
76
|
+
return numberRun(run, n);
|
|
77
|
+
}
|
|
78
|
+
return run;
|
|
79
|
+
})
|
|
80
|
+
};
|
|
81
|
+
};
|
|
82
|
+
const mapElement = (el, topLevel) => {
|
|
83
|
+
if (el.kind === "paragraph") {
|
|
84
|
+
if (topLevel) {
|
|
85
|
+
for (const r of el.paragraph.runs) if (r.footnoteRef !== void 0) paragraphFootnotes.add(r.footnoteRef);
|
|
86
|
+
}
|
|
87
|
+
return {
|
|
88
|
+
kind: "paragraph",
|
|
89
|
+
paragraph: mapParagraph(el.paragraph)
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
if (el.kind === "table") return {
|
|
93
|
+
kind: "table",
|
|
94
|
+
table: {
|
|
95
|
+
...el.table,
|
|
96
|
+
rows: el.table.rows.map((row) => ({
|
|
97
|
+
...row,
|
|
98
|
+
cells: row.cells.map((cell) => ({
|
|
99
|
+
...cell,
|
|
100
|
+
content: cell.content.map((c) => mapElement(c, false))
|
|
101
|
+
}))
|
|
102
|
+
}))
|
|
103
|
+
}
|
|
104
|
+
};
|
|
105
|
+
if (el.kind === "shape" && el.shape.text) return {
|
|
106
|
+
kind: "shape",
|
|
107
|
+
shape: {
|
|
108
|
+
...el.shape,
|
|
109
|
+
text: {
|
|
110
|
+
...el.shape.text,
|
|
111
|
+
content: el.shape.text.content.map((c) => mapElement(c, false))
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
};
|
|
115
|
+
return el;
|
|
116
|
+
};
|
|
117
|
+
const hasRefs = (els) => els.some((el) => {
|
|
118
|
+
if (el.kind === "paragraph") return el.paragraph.runs.some((r) => r.footnoteRef !== void 0 || r.endnoteRef !== void 0);
|
|
119
|
+
if (el.kind === "table") return el.table.rows.some((row) => row.cells.some((c) => hasRefs(c.content)));
|
|
120
|
+
if (el.kind === "shape" && el.shape.text) return hasRefs(el.shape.text.content);
|
|
121
|
+
return false;
|
|
122
|
+
});
|
|
123
|
+
if (!hasRefs(body)) return {
|
|
124
|
+
body,
|
|
125
|
+
footnotes,
|
|
126
|
+
endnotes,
|
|
127
|
+
deferredFootnotes: []
|
|
128
|
+
};
|
|
129
|
+
return {
|
|
130
|
+
body: body.map((el) => mapElement(el, true)),
|
|
131
|
+
footnotes,
|
|
132
|
+
endnotes,
|
|
133
|
+
deferredFootnotes: [...footnotes.keys()].filter((id) => !paragraphFootnotes.has(id))
|
|
134
|
+
};
|
|
135
|
+
}
|
|
136
|
+
function substituteNoteNumber(content, n) {
|
|
137
|
+
const hasPlaceholder = content.some((el) => el.kind === "paragraph" && el.paragraph.runs.some((r) => r.noteNumber));
|
|
138
|
+
const out = content.map((el) => {
|
|
139
|
+
if (el.kind !== "paragraph") return el;
|
|
140
|
+
if (!el.paragraph.runs.some((r) => r.noteNumber)) return el;
|
|
141
|
+
return {
|
|
142
|
+
kind: "paragraph",
|
|
143
|
+
paragraph: {
|
|
144
|
+
...el.paragraph,
|
|
145
|
+
runs: el.paragraph.runs.map((r) => r.noteNumber ? {
|
|
146
|
+
...r,
|
|
147
|
+
text: String(n),
|
|
148
|
+
properties: {
|
|
149
|
+
...r.properties,
|
|
150
|
+
verticalAlign: "superscript"
|
|
151
|
+
}
|
|
152
|
+
} : r)
|
|
153
|
+
}
|
|
154
|
+
};
|
|
155
|
+
});
|
|
156
|
+
if (hasPlaceholder || out.length === 0) return out;
|
|
157
|
+
const first = out[0];
|
|
158
|
+
if (first.kind !== "paragraph") return out;
|
|
159
|
+
return [{
|
|
160
|
+
kind: "paragraph",
|
|
161
|
+
paragraph: {
|
|
162
|
+
...first.paragraph,
|
|
163
|
+
runs: [{
|
|
164
|
+
text: `${n} `,
|
|
165
|
+
properties: { verticalAlign: "superscript" }
|
|
166
|
+
}, ...first.paragraph.runs]
|
|
167
|
+
}
|
|
168
|
+
}, ...out.slice(1)];
|
|
169
|
+
}
|
|
35
170
|
function layoutStyledDocument(body, options) {
|
|
36
171
|
const sectionList = resolveSectionList(body, options);
|
|
37
|
-
const
|
|
172
|
+
const noteAssigned = assignNoteNumbers(applyNumbering(body, options.numbering));
|
|
173
|
+
const numberedBody = noteAssigned.body;
|
|
38
174
|
const numberedHeadersFooters = applyNumberingToHeadersFooters(options.headersFooters, options.numbering);
|
|
39
175
|
const pdfaProfile = options.pdfA ? parsePdfAProfile(options.pdfA) : void 0;
|
|
40
|
-
const tagged = options.tagged === true || (pdfaProfile?.tagged ?? false);
|
|
176
|
+
const tagged = options.tagged === true || options.pdfUA === true || (pdfaProfile?.tagged ?? false);
|
|
41
177
|
const structBuilder = tagged ? new StructTreeBuilder() : void 0;
|
|
42
178
|
const fontResources = collectFontResources(numberedBody, numberedHeadersFooters, options);
|
|
43
179
|
const imageResources = collectImageResources(numberedBody, numberedHeadersFooters, options);
|
|
44
180
|
const sectionCtxs = sectionList.map((s) => buildSectionContext(s, options, numberedHeadersFooters, fontResources));
|
|
45
181
|
let sectionIdx = 0;
|
|
182
|
+
const blocks = numberedBody.map((el, idx) => {
|
|
183
|
+
while (sectionIdx < sectionCtxs.length - 1 && idx >= sectionCtxs[sectionIdx].endIndex) sectionIdx++;
|
|
184
|
+
const ctx = sectionCtxs[sectionIdx];
|
|
185
|
+
return layoutBodyElement(el, options, fontResources, imageResources, ctx.columns ? ctx.columns[0].widthPt : ctx.contentWidth, ctx.pageContentHeight);
|
|
186
|
+
});
|
|
187
|
+
const noteBlockCache = /* @__PURE__ */ new Map();
|
|
188
|
+
const notePlan = options.footnotes && noteAssigned.footnotes.size > 0 ? {
|
|
189
|
+
numbers: noteAssigned.footnotes,
|
|
190
|
+
layout: (sectionCtx, id) => {
|
|
191
|
+
let byId = noteBlockCache.get(sectionCtx);
|
|
192
|
+
if (!byId) {
|
|
193
|
+
byId = /* @__PURE__ */ new Map();
|
|
194
|
+
noteBlockCache.set(sectionCtx, byId);
|
|
195
|
+
}
|
|
196
|
+
if (byId.has(id)) return byId.get(id);
|
|
197
|
+
const content = options.footnotes?.get(id);
|
|
198
|
+
const n = noteAssigned.footnotes.get(id);
|
|
199
|
+
let laid = void 0;
|
|
200
|
+
if (content && n !== void 0 && !noteAssigned.deferredFootnotes.includes(id)) {
|
|
201
|
+
const noteBlocks = substituteNoteNumber(content, n).map((el) => layoutBodyElement(el, options, fontResources, imageResources, sectionCtx.contentWidth, sectionCtx.pageContentHeight));
|
|
202
|
+
laid = {
|
|
203
|
+
blocks: noteBlocks,
|
|
204
|
+
heightPt: noteBlocks.reduce((sum, b) => sum + (b.kind === "paragraph" ? b.spacingBeforePt + b.heightPt + b.spacingAfterPt : 0), 0)
|
|
205
|
+
};
|
|
206
|
+
}
|
|
207
|
+
byId.set(id, laid);
|
|
208
|
+
return laid;
|
|
209
|
+
}
|
|
210
|
+
} : void 0;
|
|
211
|
+
const lastCtx = sectionCtxs[sectionCtxs.length - 1];
|
|
212
|
+
if (lastCtx) {
|
|
213
|
+
const tailNotes = [];
|
|
214
|
+
for (const id of noteAssigned.deferredFootnotes) {
|
|
215
|
+
const content = options.footnotes?.get(id);
|
|
216
|
+
const n = noteAssigned.footnotes.get(id);
|
|
217
|
+
if (content && n !== void 0) tailNotes.push({
|
|
218
|
+
content,
|
|
219
|
+
n
|
|
220
|
+
});
|
|
221
|
+
}
|
|
222
|
+
for (const [id, n] of noteAssigned.endnotes) {
|
|
223
|
+
const content = options.endnotes?.get(id);
|
|
224
|
+
if (content) tailNotes.push({
|
|
225
|
+
content,
|
|
226
|
+
n
|
|
227
|
+
});
|
|
228
|
+
}
|
|
229
|
+
for (const note of tailNotes.sort((a, b) => a.n - b.n)) for (const el of substituteNoteNumber(note.content, note.n)) blocks.push(layoutBodyElement(el, options, fontResources, imageResources, lastCtx.contentWidth, lastCtx.pageContentHeight));
|
|
230
|
+
}
|
|
231
|
+
const bookmarks = /* @__PURE__ */ new Map();
|
|
232
|
+
const reflowParagraph = (paragraph, width, widths) => layoutParagraphBlock(paragraph, options, fontResources, imageResources, width, widths);
|
|
46
233
|
return {
|
|
47
|
-
pages: paginateSections(
|
|
48
|
-
while (sectionIdx < sectionCtxs.length - 1 && idx >= sectionCtxs[sectionIdx].endIndex) sectionIdx++;
|
|
49
|
-
const ctx = sectionCtxs[sectionIdx];
|
|
50
|
-
return layoutBodyElement(el, options, fontResources, imageResources, ctx.contentWidth, ctx.pageContentHeight);
|
|
51
|
-
}), sectionCtxs, structBuilder, options.language ?? "en-US"),
|
|
234
|
+
pages: paginateSections(blocks, sectionCtxs, structBuilder, options.language ?? "en-US", notePlan, bookmarks, reflowParagraph),
|
|
52
235
|
resources: options.resources ?? new ResourceStore(),
|
|
53
236
|
fontResources,
|
|
54
237
|
imageResources,
|
|
@@ -56,7 +239,8 @@ function layoutStyledDocument(body, options) {
|
|
|
56
239
|
structBuilder,
|
|
57
240
|
sectionCtxs,
|
|
58
241
|
pdfaProfile,
|
|
59
|
-
tagged
|
|
242
|
+
tagged,
|
|
243
|
+
bookmarks
|
|
60
244
|
}
|
|
61
245
|
};
|
|
62
246
|
}
|
|
@@ -99,6 +283,7 @@ function buildSectionContext(section, options, headersFooters, fontResources) {
|
|
|
99
283
|
const contentWidth = dims.pageWidth - dims.marginLeft - dims.marginRight;
|
|
100
284
|
const headerSet = layoutHeaderSet(section.properties, headersFooters, options, fontResources, contentWidth, dims.marginLeft, dims.pageHeight, dims.headerOffsetPt);
|
|
101
285
|
const footerSet = layoutFooterSet(section.properties, headersFooters, options, fontResources, contentWidth, dims.marginLeft, dims.pageHeight, dims.footerOffsetPt);
|
|
286
|
+
const columns = buildColumnGeometry(section.properties.columns, contentWidth);
|
|
102
287
|
return {
|
|
103
288
|
endIndex: section.endIndex,
|
|
104
289
|
properties: section.properties,
|
|
@@ -109,12 +294,35 @@ function buildSectionContext(section, options, headersFooters, fontResources) {
|
|
|
109
294
|
marginBottom: dims.marginBottom,
|
|
110
295
|
contentWidth,
|
|
111
296
|
pageContentHeight: dims.pageHeight - dims.marginTop - dims.marginBottom,
|
|
297
|
+
...columns ? { columns } : {},
|
|
112
298
|
headerSet,
|
|
113
299
|
footerSet,
|
|
114
300
|
titlePg: section.properties.titlePg === true,
|
|
115
301
|
evenAndOddHeaders: section.properties.evenAndOddHeaders === true
|
|
116
302
|
};
|
|
117
303
|
}
|
|
304
|
+
function buildColumnGeometry(cols, contentWidth) {
|
|
305
|
+
if (!cols || cols.count <= 1) return void 0;
|
|
306
|
+
const out = [];
|
|
307
|
+
if (cols.explicit && cols.explicit.length > 1) {
|
|
308
|
+
let x = 0;
|
|
309
|
+
for (const c of cols.explicit) {
|
|
310
|
+
out.push({
|
|
311
|
+
xOffsetPt: x,
|
|
312
|
+
widthPt: c.widthPt
|
|
313
|
+
});
|
|
314
|
+
x += c.widthPt + c.spacePt;
|
|
315
|
+
}
|
|
316
|
+
return out;
|
|
317
|
+
}
|
|
318
|
+
const width = (contentWidth - cols.spacePt * (cols.count - 1)) / cols.count;
|
|
319
|
+
if (width <= 0) return void 0;
|
|
320
|
+
for (let i = 0; i < cols.count; i++) out.push({
|
|
321
|
+
xOffsetPt: i * (width + cols.spacePt),
|
|
322
|
+
widthPt: width
|
|
323
|
+
});
|
|
324
|
+
return out;
|
|
325
|
+
}
|
|
118
326
|
function refByType(refs, type) {
|
|
119
327
|
if (!refs || refs.length === 0) return void 0;
|
|
120
328
|
return refs.find((r) => r.type === type);
|
|
@@ -128,10 +336,17 @@ function markPagination(cmds) {
|
|
|
128
336
|
function layoutHeaderSet(section, headersFooters, options, fontResources, contentWidth, marginLeft, pageHeight, headerOffsetPt) {
|
|
129
337
|
const band = (type) => {
|
|
130
338
|
const ref = refByType(section.headers, type);
|
|
131
|
-
if (!ref) return [];
|
|
339
|
+
if (!ref) return { commands: [] };
|
|
132
340
|
const content = headersFooters.get(ref.relationshipId);
|
|
133
|
-
if (!content) return [];
|
|
134
|
-
|
|
341
|
+
if (!content) return { commands: [] };
|
|
342
|
+
const render = (c) => {
|
|
343
|
+
return markPagination(drawBlocksSequentially(laidOutBlocksFor(c, options, fontResources, contentWidth), marginLeft, pageHeight - headerOffsetPt, pageHeight));
|
|
344
|
+
};
|
|
345
|
+
if (contentHasPageFields(content)) return {
|
|
346
|
+
commands: [],
|
|
347
|
+
renderDynamic: (n, total) => render(substitutePageFields(content, n, total))
|
|
348
|
+
};
|
|
349
|
+
return { commands: render(content) };
|
|
135
350
|
};
|
|
136
351
|
return {
|
|
137
352
|
default: band("default"),
|
|
@@ -142,11 +357,18 @@ function layoutHeaderSet(section, headersFooters, options, fontResources, conten
|
|
|
142
357
|
function layoutFooterSet(section, headersFooters, options, fontResources, contentWidth, marginLeft, pageHeight, footerOffsetPt) {
|
|
143
358
|
const band = (type) => {
|
|
144
359
|
const ref = refByType(section.footers, type);
|
|
145
|
-
if (!ref) return [];
|
|
360
|
+
if (!ref) return { commands: [] };
|
|
146
361
|
const content = headersFooters.get(ref.relationshipId);
|
|
147
|
-
if (!content) return [];
|
|
148
|
-
const
|
|
149
|
-
|
|
362
|
+
if (!content) return { commands: [] };
|
|
363
|
+
const render = (c) => {
|
|
364
|
+
const blocks = laidOutBlocksFor(c, options, fontResources, contentWidth);
|
|
365
|
+
return markPagination(drawBlocksSequentially(blocks, marginLeft, footerOffsetPt + blocks.reduce((sum, b) => sum + (b.kind === "paragraph" ? b.spacingBeforePt + b.heightPt + b.spacingAfterPt : b.heightPt), 0), pageHeight));
|
|
366
|
+
};
|
|
367
|
+
if (contentHasPageFields(content)) return {
|
|
368
|
+
commands: [],
|
|
369
|
+
renderDynamic: (n, total) => render(substitutePageFields(content, n, total))
|
|
370
|
+
};
|
|
371
|
+
return { commands: render(content) };
|
|
150
372
|
};
|
|
151
373
|
return {
|
|
152
374
|
default: band("default"),
|
|
@@ -154,9 +376,30 @@ function layoutFooterSet(section, headersFooters, options, fontResources, conten
|
|
|
154
376
|
even: band("even")
|
|
155
377
|
};
|
|
156
378
|
}
|
|
379
|
+
function contentHasPageFields(content) {
|
|
380
|
+
for (const el of content) if (el.kind === "paragraph" && el.paragraph.runs.some((r) => r.field !== void 0)) return true;
|
|
381
|
+
return false;
|
|
382
|
+
}
|
|
383
|
+
function substitutePageFields(content, pageNumber, totalPages) {
|
|
384
|
+
return content.map((el) => {
|
|
385
|
+
if (el.kind !== "paragraph") return el;
|
|
386
|
+
if (!el.paragraph.runs.some((r) => r.field !== void 0)) return el;
|
|
387
|
+
return {
|
|
388
|
+
kind: "paragraph",
|
|
389
|
+
paragraph: {
|
|
390
|
+
...el.paragraph,
|
|
391
|
+
runs: el.paragraph.runs.map((r) => r.field === void 0 ? r : {
|
|
392
|
+
...r,
|
|
393
|
+
text: String(r.field === "PAGE" ? pageNumber : totalPages)
|
|
394
|
+
})
|
|
395
|
+
}
|
|
396
|
+
};
|
|
397
|
+
});
|
|
398
|
+
}
|
|
157
399
|
function pickBand(set, band) {
|
|
158
|
-
|
|
159
|
-
if (band === "
|
|
400
|
+
const has = (e) => e.commands.length > 0 || e.renderDynamic !== void 0;
|
|
401
|
+
if (band === "first") return has(set.first) ? set.first : set.default;
|
|
402
|
+
if (band === "even") return has(set.even) ? set.even : set.default;
|
|
160
403
|
return set.default;
|
|
161
404
|
}
|
|
162
405
|
function bandForPage(pageInSection, globalPageIdx, titlePg, evenAndOddHeaders) {
|
|
@@ -174,7 +417,6 @@ function layoutBodyElement(el, options, fontResources, imageResources, contentWi
|
|
|
174
417
|
if (el.kind === "chart") return layoutChartBlock(el.chart, options, fontResources, contentWidth, maxHeight);
|
|
175
418
|
return layoutShapeBlock(el.shape, options, fontResources, imageResources, contentWidth, maxHeight);
|
|
176
419
|
}
|
|
177
|
-
var EMU_PER_PT = 12700;
|
|
178
420
|
function layoutImageBlock(image, imageResources, contentWidth) {
|
|
179
421
|
let widthPt = image.width;
|
|
180
422
|
let heightPt = image.height;
|
|
@@ -193,12 +435,10 @@ function layoutImageBlock(image, imageResources, contentWidth) {
|
|
|
193
435
|
resourceName: res?.resourceName ?? "",
|
|
194
436
|
spacingBeforePt: image.paragraphProperties.spacingBefore ?? 0,
|
|
195
437
|
spacingAfterPt: image.paragraphProperties.spacingAfter ?? 0,
|
|
196
|
-
...image.altText ? { altText: image.altText } : {}
|
|
438
|
+
...image.altText ? { altText: image.altText } : {},
|
|
439
|
+
...image.float ? { float: image.float } : {}
|
|
197
440
|
};
|
|
198
441
|
}
|
|
199
|
-
var DEFAULT_LINE_WIDTH_EMU = 9525;
|
|
200
|
-
var DEFAULT_INSET_LR_EMU = 91440;
|
|
201
|
-
var DEFAULT_INSET_TB_EMU = 45720;
|
|
202
442
|
function layoutShapeBlock(shape, options, fontResources, imageResources, contentWidth, maxHeight) {
|
|
203
443
|
let widthPt = shape.width;
|
|
204
444
|
let heightPt = shape.height;
|
|
@@ -218,10 +458,10 @@ function layoutShapeBlock(shape, options, fontResources, imageResources, content
|
|
|
218
458
|
const t = shape.transform;
|
|
219
459
|
const pp = shape.paragraphProperties;
|
|
220
460
|
const text = shape.text;
|
|
221
|
-
const insetLeftPt = text?.insetLeft ??
|
|
222
|
-
const insetRightPt = text?.insetRight ??
|
|
223
|
-
const insetTopPt = text?.insetTop ??
|
|
224
|
-
const insetBottomPt = text?.insetBottom ??
|
|
461
|
+
const insetLeftPt = text?.insetLeft ?? 7.2;
|
|
462
|
+
const insetRightPt = text?.insetRight ?? 7.2;
|
|
463
|
+
const insetTopPt = text?.insetTop ?? 3.6;
|
|
464
|
+
const insetBottomPt = text?.insetBottom ?? 3.6;
|
|
225
465
|
const textLines = [];
|
|
226
466
|
let textHeightPt = 0;
|
|
227
467
|
if (text && text.content.length > 0) {
|
|
@@ -256,82 +496,10 @@ function layoutShapeBlock(shape, options, fontResources, imageResources, content
|
|
|
256
496
|
insetTopPt,
|
|
257
497
|
insetBottomPt,
|
|
258
498
|
anchor: text?.anchor ?? "t",
|
|
259
|
-
...shape.altText ? { altText: shape.altText } : {}
|
|
260
|
-
|
|
261
|
-
}
|
|
262
|
-
function buildShapePaths(geometry, widthPt, heightPt) {
|
|
263
|
-
if (geometry.kind === "preset") return presetPaths(geometry.preset ?? "rect", widthPt, heightPt, geometry.adjust ?? /* @__PURE__ */ new Map()) ?? [rectPath(widthPt, heightPt)];
|
|
264
|
-
if (geometry.custom) return customPaths(geometry.custom, widthPt, heightPt);
|
|
265
|
-
return [rectPath(widthPt, heightPt)];
|
|
266
|
-
}
|
|
267
|
-
function buildStroke(line) {
|
|
268
|
-
if (!line || line.fill === "none") return void 0;
|
|
269
|
-
const widthPt = line.width ?? DEFAULT_LINE_WIDTH_EMU / EMU_PER_PT;
|
|
270
|
-
const dash = line.dash && line.dash !== "solid" ? dashPattern(line.dash, widthPt) : void 0;
|
|
271
|
-
const cap = line.cap === "flat" ? "butt" : line.cap;
|
|
272
|
-
return {
|
|
273
|
-
colorHex: line.colorHex ?? "000000",
|
|
274
|
-
widthPt,
|
|
275
|
-
...dash ? { dash } : {},
|
|
276
|
-
...cap ? { cap } : {}
|
|
499
|
+
...shape.altText ? { altText: shape.altText } : {},
|
|
500
|
+
...shape.float ? { float: shape.float } : {}
|
|
277
501
|
};
|
|
278
502
|
}
|
|
279
|
-
function dashPattern(dash, w) {
|
|
280
|
-
const u = Math.max(w, .1);
|
|
281
|
-
switch (dash) {
|
|
282
|
-
case "solid": return;
|
|
283
|
-
case "dot": return [u, 2 * u];
|
|
284
|
-
case "dash": return [4 * u, 3 * u];
|
|
285
|
-
case "dashDot": return [
|
|
286
|
-
4 * u,
|
|
287
|
-
3 * u,
|
|
288
|
-
u,
|
|
289
|
-
3 * u
|
|
290
|
-
];
|
|
291
|
-
case "lgDash": return [8 * u, 3 * u];
|
|
292
|
-
case "lgDashDot": return [
|
|
293
|
-
8 * u,
|
|
294
|
-
3 * u,
|
|
295
|
-
u,
|
|
296
|
-
3 * u
|
|
297
|
-
];
|
|
298
|
-
case "sysDash": return [3 * u, u];
|
|
299
|
-
case "sysDot": return [u, u];
|
|
300
|
-
}
|
|
301
|
-
}
|
|
302
|
-
function buildShapeTransform(pageX, pageY, widthPt, heightPt, rotation60k, flipH, flipV) {
|
|
303
|
-
const theta = -rotation60k / 6e4 * (Math.PI / 180);
|
|
304
|
-
const sx = flipH ? -1 : 1;
|
|
305
|
-
const sy = flipV ? -1 : 1;
|
|
306
|
-
const cos = Math.cos(theta);
|
|
307
|
-
const sin = Math.sin(theta);
|
|
308
|
-
const a = sx * cos;
|
|
309
|
-
const b = sx * sin;
|
|
310
|
-
const c = -sy * sin;
|
|
311
|
-
const d = sy * cos;
|
|
312
|
-
const cxL = widthPt / 2;
|
|
313
|
-
const cyL = heightPt / 2;
|
|
314
|
-
const centerX = pageX + cxL;
|
|
315
|
-
const centerY = pageY + cyL;
|
|
316
|
-
return [
|
|
317
|
-
a,
|
|
318
|
-
b,
|
|
319
|
-
c,
|
|
320
|
-
d,
|
|
321
|
-
centerX - (a * cxL + c * cyL),
|
|
322
|
-
centerY - (b * cxL + d * cyL)
|
|
323
|
-
];
|
|
324
|
-
}
|
|
325
|
-
function flipTransform(m, pageHeight) {
|
|
326
|
-
return [
|
|
327
|
-
m[0],
|
|
328
|
-
-m[1],
|
|
329
|
-
m[2],
|
|
330
|
-
-m[3],
|
|
331
|
-
m[4],
|
|
332
|
-
pageHeight - m[5]
|
|
333
|
-
];
|
|
334
|
-
}
|
|
335
503
|
function layoutChartBlock(block, options, fontResources, contentWidth, maxHeight) {
|
|
336
504
|
let widthPt = block.width;
|
|
337
505
|
let heightPt = block.height;
|
|
@@ -362,7 +530,8 @@ function layoutChartBlock(block, options, fontResources, contentWidth, maxHeight
|
|
|
362
530
|
resolvedAlignment: pp.alignment ?? "left",
|
|
363
531
|
spacingBeforePt: pp.spacingBefore ?? 0,
|
|
364
532
|
spacingAfterPt: pp.spacingAfter ?? 0,
|
|
365
|
-
...altText ? { altText } : {}
|
|
533
|
+
...altText ? { altText } : {},
|
|
534
|
+
...block.float ? { float: block.float } : {}
|
|
366
535
|
};
|
|
367
536
|
}
|
|
368
537
|
function buildChartLayout(chart, widthPt, heightPt, font) {
|
|
@@ -486,6 +655,8 @@ function collectImageResources(body, headersFooters, options) {
|
|
|
486
655
|
};
|
|
487
656
|
visit(body);
|
|
488
657
|
for (const hf of headersFooters.values()) visit(hf);
|
|
658
|
+
for (const note of options.footnotes?.values() ?? []) visit(note);
|
|
659
|
+
for (const note of options.endnotes?.values() ?? []) visit(note);
|
|
489
660
|
const flattenAlpha = options.pdfA ? parsePdfAProfile(options.pdfA).part === 1 : false;
|
|
490
661
|
let counter = 0;
|
|
491
662
|
for (const resourceId of seen) {
|
|
@@ -505,7 +676,7 @@ function collectImageResources(body, headersFooters, options) {
|
|
|
505
676
|
}
|
|
506
677
|
return out;
|
|
507
678
|
}
|
|
508
|
-
function drawBlocksSequentially(blocks, startX, startY, pageHeight) {
|
|
679
|
+
function drawBlocksSequentially(blocks, startX, startY, pageHeight, structId) {
|
|
509
680
|
const out = [];
|
|
510
681
|
let cursorY = startY;
|
|
511
682
|
for (const block of blocks) {
|
|
@@ -520,7 +691,8 @@ function drawBlocksSequentially(blocks, startX, startY, pageHeight) {
|
|
|
520
691
|
type: "line",
|
|
521
692
|
line,
|
|
522
693
|
originX: pt(startX + indentLeft + offset),
|
|
523
|
-
baselineY: pt(pageHeight - (cursorY + lineDescent(line)))
|
|
694
|
+
baselineY: pt(pageHeight - (cursorY + lineDescent(line))),
|
|
695
|
+
...structId !== void 0 ? { structId } : {}
|
|
524
696
|
});
|
|
525
697
|
}
|
|
526
698
|
cursorY -= block.spacingAfterPt;
|
|
@@ -600,6 +772,20 @@ function collectFontResources(body, headersFooters, options) {
|
|
|
600
772
|
continue;
|
|
601
773
|
}
|
|
602
774
|
if (run.inlineImage && !run.text) continue;
|
|
775
|
+
if (run.field !== void 0) {
|
|
776
|
+
addRun({
|
|
777
|
+
text: `${run.text}0123456789`,
|
|
778
|
+
properties: run.properties
|
|
779
|
+
}, el.paragraph);
|
|
780
|
+
continue;
|
|
781
|
+
}
|
|
782
|
+
if (run.footnoteRef !== void 0 || run.endnoteRef !== void 0 || run.noteNumber) {
|
|
783
|
+
addRun({
|
|
784
|
+
text: `${run.text}0123456789 `,
|
|
785
|
+
properties: run.properties
|
|
786
|
+
}, el.paragraph);
|
|
787
|
+
continue;
|
|
788
|
+
}
|
|
603
789
|
addRun(run, el.paragraph);
|
|
604
790
|
}
|
|
605
791
|
else if (el.kind === "table") for (const row of el.table.rows) for (const cell of row.cells) visit(cell.content);
|
|
@@ -629,6 +815,8 @@ function collectFontResources(body, headersFooters, options) {
|
|
|
629
815
|
};
|
|
630
816
|
visit(body);
|
|
631
817
|
for (const hf of headersFooters.values()) visit(hf);
|
|
818
|
+
for (const note of options.footnotes?.values() ?? []) visit(note);
|
|
819
|
+
for (const note of options.endnotes?.values() ?? []) visit(note);
|
|
632
820
|
if (used.size === 0) {
|
|
633
821
|
const regular = options.registry.resolveByStyle(false, false);
|
|
634
822
|
used.set(regular.variant, {
|
|
@@ -650,14 +838,14 @@ function collectFontResources(body, headersFooters, options) {
|
|
|
650
838
|
}
|
|
651
839
|
return out;
|
|
652
840
|
}
|
|
653
|
-
function layoutParagraphBlock(paragraph, options, fontResources, imageResources, contentWidth) {
|
|
841
|
+
function layoutParagraphBlock(paragraph, options, fontResources, imageResources, contentWidth, lineWidths) {
|
|
654
842
|
const baseResolved = resolveParagraphProperties(paragraph.properties, options.styles);
|
|
655
843
|
const baseDir = paragraphBaseDirection(paragraph, baseResolved);
|
|
656
844
|
const resolved = baseDir === "rtl" && baseResolved.alignment === "left" ? {
|
|
657
845
|
...baseResolved,
|
|
658
846
|
alignment: "right"
|
|
659
847
|
} : baseResolved;
|
|
660
|
-
const lines = wrap(tokenizeParagraph(paragraph, options, fontResources, imageResources, contentWidth, baseDir), paragraphMaxWidth(resolved, contentWidth, true), paragraphMaxWidth(resolved, contentWidth, false), resolved, options.hyphenator);
|
|
848
|
+
const lines = wrap(tokenizeParagraph(paragraph, options, fontResources, imageResources, contentWidth, baseDir), paragraphMaxWidth(resolved, contentWidth, true), paragraphMaxWidth(resolved, contentWidth, false), resolved, options.hyphenator, lineWidths);
|
|
661
849
|
let heightPt = 0;
|
|
662
850
|
for (const line of lines) heightPt += computeLineHeight(line, resolved);
|
|
663
851
|
const numbering = paragraph.properties.numbering;
|
|
@@ -672,7 +860,9 @@ function layoutParagraphBlock(paragraph, options, fontResources, imageResources,
|
|
|
672
860
|
numId: numbering.numId,
|
|
673
861
|
level: numbering.ilvl
|
|
674
862
|
} } : {},
|
|
675
|
-
...paragraph.runs.some((r) => r.pageBreak) ? { pageBreakAfter: true } : {}
|
|
863
|
+
...paragraph.runs.some((r) => r.pageBreak) ? { pageBreakAfter: true } : {},
|
|
864
|
+
...paragraph.bookmarks && paragraph.bookmarks.length > 0 ? { bookmarks: paragraph.bookmarks } : {},
|
|
865
|
+
source: paragraph
|
|
676
866
|
};
|
|
677
867
|
}
|
|
678
868
|
function resolveMathItems(items, fontFor) {
|
|
@@ -801,6 +991,10 @@ function tokenizePlansLtr(plans) {
|
|
|
801
991
|
kind: "text",
|
|
802
992
|
text: t.text,
|
|
803
993
|
isSpace: t.isSpace,
|
|
994
|
+
...plan.run.href !== void 0 ? { href: plan.run.href } : {},
|
|
995
|
+
...plan.run.footnoteRef !== void 0 ? { footnoteRef: plan.run.footnoteRef } : {},
|
|
996
|
+
...plan.run.anchor !== void 0 ? { anchor: plan.run.anchor } : {},
|
|
997
|
+
...plan.run.listMarker ? { listMarker: true } : {},
|
|
804
998
|
resolvedRun: plan.resolvedRun,
|
|
805
999
|
font: plan.font,
|
|
806
1000
|
fontSizePt: plan.fontSizePt,
|
|
@@ -851,6 +1045,10 @@ function tokenizePlansBidi(plans, realLevels) {
|
|
|
851
1045
|
kind: "text",
|
|
852
1046
|
text,
|
|
853
1047
|
isSpace: curSpace,
|
|
1048
|
+
...plan.run.href !== void 0 ? { href: plan.run.href } : {},
|
|
1049
|
+
...plan.run.footnoteRef !== void 0 ? { footnoteRef: plan.run.footnoteRef } : {},
|
|
1050
|
+
...plan.run.anchor !== void 0 ? { anchor: plan.run.anchor } : {},
|
|
1051
|
+
...plan.run.listMarker ? { listMarker: true } : {},
|
|
854
1052
|
resolvedRun: plan.resolvedRun,
|
|
855
1053
|
font: plan.font,
|
|
856
1054
|
fontSizePt: plan.fontSizePt,
|
|
@@ -1041,18 +1239,22 @@ function lineFromRange(entries, start, breakIdx, availableWidthPt, isFirst, reso
|
|
|
1041
1239
|
mathDescentPt: mathDescent
|
|
1042
1240
|
};
|
|
1043
1241
|
}
|
|
1044
|
-
function wrap(tokens, firstLineWidth, otherWidth, resolved, hyphenator) {
|
|
1242
|
+
function wrap(tokens, firstLineWidth, otherWidth, resolved, hyphenator, lineWidths) {
|
|
1045
1243
|
if (tokens.length === 0) return [];
|
|
1244
|
+
const widths = lineWidths ?? [firstLineWidth, otherWidth];
|
|
1046
1245
|
const entries = paragraphItemStream(tokens, hyphenator);
|
|
1047
|
-
const { breaks } = breakLines(entries.map((e) => e.item),
|
|
1246
|
+
const { breaks } = breakLines(entries.map((e) => e.item), widths);
|
|
1048
1247
|
const lines = [];
|
|
1049
1248
|
let start = 0;
|
|
1050
1249
|
let isFirst = true;
|
|
1250
|
+
let lineIdx = 0;
|
|
1051
1251
|
for (const breakIdx of breaks) {
|
|
1052
|
-
const
|
|
1252
|
+
const width = lineIdx < widths.length ? widths[lineIdx] : widths[widths.length - 1];
|
|
1253
|
+
const line = lineFromRange(entries, start, breakIdx, width, isFirst, resolved);
|
|
1053
1254
|
if (line) lines.push(line);
|
|
1054
1255
|
start = breakIdx + 1;
|
|
1055
1256
|
isFirst = false;
|
|
1257
|
+
lineIdx++;
|
|
1056
1258
|
}
|
|
1057
1259
|
if (lines.length > 0) lines[lines.length - 1].isLastInParagraph = true;
|
|
1058
1260
|
return lines;
|
|
@@ -1344,7 +1546,7 @@ function createFigure(builder, alt, fallback) {
|
|
|
1344
1546
|
node.alt = alt && alt.trim().length > 0 ? alt : fallback;
|
|
1345
1547
|
return node.id;
|
|
1346
1548
|
}
|
|
1347
|
-
function listItemParagraphNode(builder, stack, list) {
|
|
1549
|
+
function listItemParagraphNode(builder, stack, list, wantLbl) {
|
|
1348
1550
|
const lvl = list.level;
|
|
1349
1551
|
while (stack.length > 0) {
|
|
1350
1552
|
const t = stack[stack.length - 1];
|
|
@@ -1364,168 +1566,445 @@ function listItemParagraphNode(builder, stack, list) {
|
|
|
1364
1566
|
stack.push(frame);
|
|
1365
1567
|
}
|
|
1366
1568
|
const li = builder.create("LI", frame.listNode);
|
|
1569
|
+
const lblId = wantLbl ? builder.create("Lbl", li).id : void 0;
|
|
1367
1570
|
const lbody = builder.create("LBody", li);
|
|
1368
1571
|
frame.lbody = lbody;
|
|
1369
|
-
return
|
|
1572
|
+
return {
|
|
1573
|
+
pId: builder.create("P", lbody).id,
|
|
1574
|
+
...lblId !== void 0 ? { lblId } : {}
|
|
1575
|
+
};
|
|
1370
1576
|
}
|
|
1371
|
-
|
|
1372
|
-
|
|
1373
|
-
|
|
1374
|
-
|
|
1375
|
-
|
|
1376
|
-
|
|
1377
|
-
|
|
1378
|
-
|
|
1379
|
-
|
|
1380
|
-
|
|
1381
|
-
|
|
1382
|
-
|
|
1383
|
-
|
|
1384
|
-
|
|
1385
|
-
|
|
1386
|
-
|
|
1387
|
-
|
|
1577
|
+
var PageAssembler = class {
|
|
1578
|
+
constructor(sectionCtxs, builder, notes, bookmarkPositions) {
|
|
1579
|
+
this.sectionCtxs = sectionCtxs;
|
|
1580
|
+
this.builder = builder;
|
|
1581
|
+
this.notes = notes;
|
|
1582
|
+
this.bookmarkPositions = bookmarkPositions;
|
|
1583
|
+
this.ctx = sectionCtxs[0];
|
|
1584
|
+
this.cursorY = this.ctx.pageHeight - this.ctx.marginTop;
|
|
1585
|
+
}
|
|
1586
|
+
pages = [];
|
|
1587
|
+
ctx;
|
|
1588
|
+
secIdx = 0;
|
|
1589
|
+
pageInSection = 0;
|
|
1590
|
+
globalPageIdx = 0;
|
|
1591
|
+
current = [];
|
|
1592
|
+
pendingPageBreak = false;
|
|
1593
|
+
cursorY;
|
|
1594
|
+
colIdx = 0;
|
|
1595
|
+
colStartLen = 0;
|
|
1596
|
+
colLeft = () => this.ctx.marginLeft + (this.ctx.columns?.[this.colIdx]?.xOffsetPt ?? 0);
|
|
1597
|
+
colWidth = () => this.ctx.columns?.[this.colIdx]?.widthPt ?? this.ctx.contentWidth;
|
|
1598
|
+
colHasContent = () => this.current.length > this.colStartLen;
|
|
1599
|
+
advanceColumn = () => {
|
|
1600
|
+
if (this.ctx.columns && this.colIdx + 1 < this.ctx.columns.length) {
|
|
1601
|
+
this.colIdx++;
|
|
1602
|
+
this.colStartLen = this.current.length;
|
|
1603
|
+
this.cursorY = this.ctx.pageHeight - this.ctx.marginTop;
|
|
1604
|
+
} else this.flushPage();
|
|
1605
|
+
};
|
|
1606
|
+
floatsBehind = [];
|
|
1607
|
+
floatsFront = [];
|
|
1608
|
+
exclusions = [];
|
|
1609
|
+
floatX = (f, widthPt) => {
|
|
1610
|
+
const h = f.posH;
|
|
1611
|
+
if (!h) return this.colLeft();
|
|
1612
|
+
const base = h.relativeFrom === "page" ? 0 : h.relativeFrom === "column" ? this.colLeft() : this.ctx.marginLeft;
|
|
1613
|
+
const span = h.relativeFrom === "page" ? this.ctx.pageWidth : h.relativeFrom === "column" ? this.colWidth() : this.ctx.contentWidth;
|
|
1614
|
+
if (h.align === "center") return base + (span - widthPt) / 2;
|
|
1615
|
+
if (h.align === "right") return base + span - widthPt;
|
|
1616
|
+
return base + (h.offsetPt ?? 0);
|
|
1617
|
+
};
|
|
1618
|
+
floatTopYUp = (f) => {
|
|
1619
|
+
const v = f.posV;
|
|
1620
|
+
if (!v) return this.cursorY;
|
|
1621
|
+
if (v.relativeFrom === "page") return this.ctx.pageHeight - (v.offsetPt ?? 0);
|
|
1622
|
+
if (v.relativeFrom === "margin") return this.ctx.pageHeight - this.ctx.marginTop - (v.offsetPt ?? 0);
|
|
1623
|
+
return this.cursorY - (v.offsetPt ?? 0);
|
|
1624
|
+
};
|
|
1625
|
+
listStack = [];
|
|
1626
|
+
pageNotes = [];
|
|
1627
|
+
noteReserve = 0;
|
|
1628
|
+
placedNotes = /* @__PURE__ */ new Set();
|
|
1629
|
+
bottomLimit = () => this.ctx.marginBottom + this.noteReserve;
|
|
1630
|
+
exclusionAt = (yTop, h) => {
|
|
1631
|
+
const cl = this.colLeft();
|
|
1632
|
+
const cr = cl + this.colWidth();
|
|
1633
|
+
for (const e of this.exclusions) {
|
|
1634
|
+
if (yTop - h >= e.topYUp || yTop <= e.bottomYUp) continue;
|
|
1635
|
+
if (e.x1 <= cl || e.x0 >= cr) continue;
|
|
1636
|
+
return e;
|
|
1637
|
+
}
|
|
1638
|
+
};
|
|
1639
|
+
lineGeometryAt = (yTop, h) => {
|
|
1640
|
+
const full = this.colWidth();
|
|
1641
|
+
const e = this.exclusionAt(yTop, h);
|
|
1642
|
+
if (!e) return {
|
|
1643
|
+
width: full,
|
|
1644
|
+
xOffset: 0
|
|
1645
|
+
};
|
|
1646
|
+
const cl = this.colLeft();
|
|
1647
|
+
const leftRoom = e.x0 - FLOAT_TEXT_GAP - cl;
|
|
1648
|
+
const rightRoom = cl + full - (e.x1 + FLOAT_TEXT_GAP);
|
|
1649
|
+
if (rightRoom >= leftRoom) {
|
|
1650
|
+
const w = Math.max(MIN_WRAP_WIDTH, rightRoom);
|
|
1651
|
+
return {
|
|
1652
|
+
width: w,
|
|
1653
|
+
xOffset: full - w
|
|
1654
|
+
};
|
|
1655
|
+
}
|
|
1656
|
+
return {
|
|
1657
|
+
width: Math.max(MIN_WRAP_WIDTH, leftRoom),
|
|
1658
|
+
xOffset: 0
|
|
1659
|
+
};
|
|
1660
|
+
};
|
|
1661
|
+
lineWidthsFor = (block, startY) => {
|
|
1662
|
+
if (this.exclusions.length === 0 || block.lines.length === 0) return void 0;
|
|
1663
|
+
const h0 = computeLineHeight(block.lines[0], block.resolved);
|
|
1664
|
+
if (h0 <= 0) return void 0;
|
|
1665
|
+
const widths = [];
|
|
1666
|
+
let narrowed = false;
|
|
1667
|
+
let y = startY;
|
|
1668
|
+
for (let i = 0; i < 200; i++) {
|
|
1669
|
+
const g = this.lineGeometryAt(y, h0);
|
|
1670
|
+
widths.push(g.width);
|
|
1671
|
+
if (g.width < this.colWidth()) narrowed = true;
|
|
1672
|
+
else if (i > 0) break;
|
|
1673
|
+
y -= h0;
|
|
1674
|
+
if (y < this.bottomLimit()) break;
|
|
1675
|
+
}
|
|
1676
|
+
return narrowed ? widths : void 0;
|
|
1677
|
+
};
|
|
1678
|
+
lineFootnotes = (line) => {
|
|
1679
|
+
if (!this.notes) return [];
|
|
1680
|
+
const out = [];
|
|
1681
|
+
for (const tok of line.tokens) {
|
|
1682
|
+
if (tok.kind !== "text" || tok.footnoteRef === void 0) continue;
|
|
1683
|
+
const id = tok.footnoteRef;
|
|
1684
|
+
if (this.placedNotes.has(id) || out.some((o) => o.id === id)) continue;
|
|
1685
|
+
const laid = this.notes.layout(this.ctx, id);
|
|
1686
|
+
const n = this.notes.numbers.get(id);
|
|
1687
|
+
if (!laid || n === void 0) continue;
|
|
1688
|
+
out.push({
|
|
1689
|
+
id,
|
|
1690
|
+
n,
|
|
1691
|
+
blocks: laid.blocks,
|
|
1692
|
+
heightPt: laid.heightPt
|
|
1693
|
+
});
|
|
1694
|
+
}
|
|
1695
|
+
return out;
|
|
1696
|
+
};
|
|
1697
|
+
renderNotesBand = () => {
|
|
1698
|
+
if (this.pageNotes.length === 0) return [];
|
|
1699
|
+
const out = [];
|
|
1700
|
+
const top = this.ctx.marginBottom + this.noteReserve;
|
|
1701
|
+
out.push({
|
|
1702
|
+
type: "fill",
|
|
1703
|
+
x: pt(this.ctx.marginLeft),
|
|
1704
|
+
y: pt(this.ctx.pageHeight - (top - FOOTNOTE_RULE_GAP_ABOVE)),
|
|
1705
|
+
width: pt(FOOTNOTE_RULE_WIDTH),
|
|
1706
|
+
height: pt(FOOTNOTE_RULE_PT),
|
|
1707
|
+
fillColorHex: "000000"
|
|
1708
|
+
});
|
|
1709
|
+
let cursor = top - FOOTNOTE_SEPARATOR_HEIGHT;
|
|
1710
|
+
for (const note of this.pageNotes.sort((a, b) => a.n - b.n)) {
|
|
1711
|
+
let structId;
|
|
1712
|
+
if (this.builder) {
|
|
1713
|
+
const noteNode = this.builder.create("Note", this.builder.root);
|
|
1714
|
+
structId = this.builder.create("P", noteNode).id;
|
|
1715
|
+
}
|
|
1716
|
+
out.push(...drawBlocksSequentially(note.blocks, this.ctx.marginLeft, cursor, this.ctx.pageHeight, structId));
|
|
1717
|
+
cursor -= note.heightPt;
|
|
1718
|
+
}
|
|
1719
|
+
return out;
|
|
1720
|
+
};
|
|
1721
|
+
dynBands = [];
|
|
1722
|
+
flushPage = (force = false) => {
|
|
1723
|
+
if (this.current.length === 0 && !force) return;
|
|
1724
|
+
const band = bandForPage(this.pageInSection, this.globalPageIdx, this.ctx.titlePg, this.ctx.evenAndOddHeaders);
|
|
1725
|
+
const header = pickBand(this.ctx.headerSet, band);
|
|
1726
|
+
const footer = pickBand(this.ctx.footerSet, band);
|
|
1727
|
+
if (header.renderDynamic) this.dynBands.push({
|
|
1728
|
+
pageIdx: this.pages.length,
|
|
1729
|
+
pageNumber: this.globalPageIdx + 1,
|
|
1730
|
+
position: "header",
|
|
1731
|
+
render: header.renderDynamic
|
|
1732
|
+
});
|
|
1733
|
+
if (footer.renderDynamic) this.dynBands.push({
|
|
1734
|
+
pageIdx: this.pages.length,
|
|
1735
|
+
pageNumber: this.globalPageIdx + 1,
|
|
1736
|
+
position: "footer",
|
|
1737
|
+
render: footer.renderDynamic
|
|
1738
|
+
});
|
|
1739
|
+
this.pages.push({
|
|
1388
1740
|
commands: [
|
|
1389
|
-
...header,
|
|
1390
|
-
...
|
|
1391
|
-
...
|
|
1741
|
+
...header.commands,
|
|
1742
|
+
...this.floatsBehind,
|
|
1743
|
+
...this.current,
|
|
1744
|
+
...this.floatsFront,
|
|
1745
|
+
...this.renderNotesBand(),
|
|
1746
|
+
...footer.commands
|
|
1392
1747
|
],
|
|
1393
|
-
width: pt(ctx.pageWidth),
|
|
1394
|
-
height: pt(ctx.pageHeight)
|
|
1748
|
+
width: pt(this.ctx.pageWidth),
|
|
1749
|
+
height: pt(this.ctx.pageHeight)
|
|
1395
1750
|
});
|
|
1396
|
-
current = [];
|
|
1397
|
-
|
|
1398
|
-
|
|
1399
|
-
|
|
1751
|
+
this.current = [];
|
|
1752
|
+
this.floatsBehind = [];
|
|
1753
|
+
this.floatsFront = [];
|
|
1754
|
+
this.exclusions = [];
|
|
1755
|
+
this.pageNotes = [];
|
|
1756
|
+
this.noteReserve = 0;
|
|
1757
|
+
this.colIdx = 0;
|
|
1758
|
+
this.colStartLen = 0;
|
|
1759
|
+
this.pageInSection++;
|
|
1760
|
+
this.globalPageIdx++;
|
|
1761
|
+
this.cursorY = this.ctx.pageHeight - this.ctx.marginTop;
|
|
1400
1762
|
};
|
|
1763
|
+
};
|
|
1764
|
+
function paginateSections(blocks, sectionCtxs, builder, defaultLang = "en-US", notes, bookmarkPositions, reflowParagraph) {
|
|
1765
|
+
if (sectionCtxs.length === 0) return [];
|
|
1766
|
+
const asm = new PageAssembler(sectionCtxs, builder, notes, bookmarkPositions);
|
|
1401
1767
|
for (let blockIdx = 0; blockIdx < blocks.length; blockIdx++) {
|
|
1402
|
-
while (secIdx < sectionCtxs.length - 1 && blockIdx >= ctx.endIndex) {
|
|
1403
|
-
flushPage();
|
|
1404
|
-
secIdx++;
|
|
1405
|
-
ctx = sectionCtxs[secIdx];
|
|
1406
|
-
pageInSection = 0;
|
|
1407
|
-
cursorY = ctx.pageHeight - ctx.marginTop;
|
|
1768
|
+
while (asm.secIdx < sectionCtxs.length - 1 && blockIdx >= asm.ctx.endIndex) {
|
|
1769
|
+
asm.flushPage();
|
|
1770
|
+
asm.secIdx++;
|
|
1771
|
+
asm.ctx = sectionCtxs[asm.secIdx];
|
|
1772
|
+
asm.pageInSection = 0;
|
|
1773
|
+
asm.cursorY = asm.ctx.pageHeight - asm.ctx.marginTop;
|
|
1408
1774
|
}
|
|
1409
1775
|
const block = blocks[blockIdx];
|
|
1410
|
-
if (pendingPageBreak) {
|
|
1411
|
-
pendingPageBreak = false;
|
|
1412
|
-
if (current.length > 0) flushPage();
|
|
1776
|
+
if (asm.pendingPageBreak) {
|
|
1777
|
+
asm.pendingPageBreak = false;
|
|
1778
|
+
if (asm.current.length > 0) asm.flushPage();
|
|
1413
1779
|
}
|
|
1414
|
-
if (builder && !(block.kind === "paragraph" && block.list)) listStack.length = 0;
|
|
1780
|
+
if (builder && !(block.kind === "paragraph" && block.list)) asm.listStack.length = 0;
|
|
1415
1781
|
if (block.kind === "paragraph") {
|
|
1416
|
-
if (block.resolved.pageBreakBefore && current.length > 0) flushPage();
|
|
1417
|
-
cursorY -= block.spacingBeforePt;
|
|
1782
|
+
if (block.resolved.pageBreakBefore && asm.current.length > 0) asm.flushPage();
|
|
1783
|
+
asm.cursorY -= block.spacingBeforePt;
|
|
1784
|
+
let pb = block;
|
|
1785
|
+
if (reflowParagraph && pb.source && asm.exclusions.length > 0) {
|
|
1786
|
+
const widths = asm.lineWidthsFor(block, asm.cursorY);
|
|
1787
|
+
if (widths) pb = reflowParagraph(pb.source, asm.colWidth(), widths);
|
|
1788
|
+
}
|
|
1418
1789
|
let structId;
|
|
1790
|
+
let markerLblId;
|
|
1791
|
+
const firstLine = pb.lines[0];
|
|
1792
|
+
const splitMarker = builder !== void 0 && pb.list !== void 0 && firstLine !== void 0 && pb.resolved.alignment === "left" && pb.resolved.bidi !== true && !firstLine.tokens.some((t) => t.bidiLevel % 2 === 1) && firstLine.tokens.some((t) => t.kind === "text" && t.listMarker) && firstLine.tokens.some((t) => !(t.kind === "text" && t.listMarker));
|
|
1419
1793
|
if (builder) {
|
|
1420
|
-
|
|
1421
|
-
|
|
1794
|
+
if (pb.list) {
|
|
1795
|
+
const nodes = listItemParagraphNode(builder, asm.listStack, pb.list, splitMarker);
|
|
1796
|
+
structId = nodes.pId;
|
|
1797
|
+
markerLblId = nodes.lblId;
|
|
1798
|
+
} else structId = builder.create(paragraphStructType(pb.resolved), builder.root).id;
|
|
1799
|
+
const lang = dominantParagraphLang(pb.lines);
|
|
1422
1800
|
if (lang && lang !== defaultLang) builder.node(structId).lang = lang;
|
|
1423
1801
|
}
|
|
1424
|
-
|
|
1425
|
-
|
|
1426
|
-
|
|
1427
|
-
|
|
1428
|
-
const
|
|
1429
|
-
|
|
1430
|
-
|
|
1802
|
+
let firstLineOfBlock = true;
|
|
1803
|
+
for (const line of pb.lines) {
|
|
1804
|
+
const h = computeLineHeight(line, pb.resolved);
|
|
1805
|
+
let newNotes = asm.lineFootnotes(line);
|
|
1806
|
+
const addedReserve = (sub) => sub.reduce((sum, x) => sum + x.heightPt, 0) + (asm.pageNotes.length === 0 && sub.length > 0 ? FOOTNOTE_SEPARATOR_HEIGHT : 0);
|
|
1807
|
+
if (asm.cursorY - h < asm.bottomLimit() + addedReserve(newNotes) && asm.colHasContent()) {
|
|
1808
|
+
asm.advanceColumn();
|
|
1809
|
+
newNotes = asm.lineFootnotes(line);
|
|
1810
|
+
}
|
|
1811
|
+
if (newNotes.length > 0) {
|
|
1812
|
+
asm.noteReserve += addedReserve(newNotes);
|
|
1813
|
+
for (const x of newNotes) {
|
|
1814
|
+
asm.placedNotes.add(x.id);
|
|
1815
|
+
asm.pageNotes.push({
|
|
1816
|
+
n: x.n,
|
|
1817
|
+
blocks: x.blocks,
|
|
1818
|
+
heightPt: x.heightPt
|
|
1819
|
+
});
|
|
1820
|
+
}
|
|
1821
|
+
}
|
|
1822
|
+
if (firstLineOfBlock) {
|
|
1823
|
+
firstLineOfBlock = false;
|
|
1824
|
+
if (pb.bookmarks && asm.bookmarkPositions) {
|
|
1825
|
+
for (const bookmarkName of pb.bookmarks) if (!asm.bookmarkPositions.has(bookmarkName)) asm.bookmarkPositions.set(bookmarkName, {
|
|
1826
|
+
pageIdx: asm.pages.length,
|
|
1827
|
+
yTopPt: asm.cursorY
|
|
1828
|
+
});
|
|
1829
|
+
}
|
|
1830
|
+
}
|
|
1831
|
+
asm.cursorY -= h;
|
|
1832
|
+
const indentLeft = pb.resolved.indentLeft + (line.firstLine ? pb.resolved.indentFirstLine : 0);
|
|
1833
|
+
const offset = alignmentOffset(pb.resolved.alignment, line.contentWidthPt, line.availableWidthPt);
|
|
1834
|
+
const baselineY = pt(asm.ctx.pageHeight - (asm.cursorY + lineDescent(line)));
|
|
1835
|
+
const exclusionShift = asm.exclusions.length > 0 ? asm.lineGeometryAt(asm.cursorY + h, h).xOffset : 0;
|
|
1836
|
+
const originX = asm.colLeft() + indentLeft + offset + exclusionShift;
|
|
1837
|
+
if (markerLblId !== void 0 && line === firstLine) {
|
|
1838
|
+
let k = 0;
|
|
1839
|
+
let markerWidth = 0;
|
|
1840
|
+
while (k < line.tokens.length) {
|
|
1841
|
+
const t = line.tokens[k];
|
|
1842
|
+
if (t.kind !== "text" || !t.listMarker) break;
|
|
1843
|
+
markerWidth += t.widthPt;
|
|
1844
|
+
k++;
|
|
1845
|
+
}
|
|
1846
|
+
asm.current.push({
|
|
1847
|
+
type: "line",
|
|
1848
|
+
line: {
|
|
1849
|
+
...line,
|
|
1850
|
+
tokens: line.tokens.slice(0, k),
|
|
1851
|
+
isLastInParagraph: false
|
|
1852
|
+
},
|
|
1853
|
+
originX: pt(originX),
|
|
1854
|
+
baselineY,
|
|
1855
|
+
structId: markerLblId
|
|
1856
|
+
});
|
|
1857
|
+
asm.current.push({
|
|
1858
|
+
type: "line",
|
|
1859
|
+
line: {
|
|
1860
|
+
...line,
|
|
1861
|
+
tokens: line.tokens.slice(k)
|
|
1862
|
+
},
|
|
1863
|
+
originX: pt(originX + markerWidth),
|
|
1864
|
+
baselineY,
|
|
1865
|
+
...structId !== void 0 ? { structId } : {}
|
|
1866
|
+
});
|
|
1867
|
+
} else asm.current.push({
|
|
1431
1868
|
type: "line",
|
|
1432
1869
|
line,
|
|
1433
|
-
originX: pt(
|
|
1434
|
-
baselineY
|
|
1870
|
+
originX: pt(originX),
|
|
1871
|
+
baselineY,
|
|
1435
1872
|
...structId !== void 0 ? { structId } : {}
|
|
1436
1873
|
});
|
|
1437
1874
|
}
|
|
1438
|
-
cursorY -=
|
|
1439
|
-
if (
|
|
1875
|
+
asm.cursorY -= pb.spacingAfterPt;
|
|
1876
|
+
if (pb.pageBreakAfter) asm.pendingPageBreak = true;
|
|
1440
1877
|
} else if (block.kind === "image") {
|
|
1441
1878
|
const figId = builder ? createFigure(builder, block.altText, "Image") : void 0;
|
|
1442
|
-
|
|
1443
|
-
|
|
1444
|
-
|
|
1445
|
-
|
|
1446
|
-
|
|
1447
|
-
|
|
1448
|
-
|
|
1449
|
-
|
|
1450
|
-
|
|
1451
|
-
|
|
1452
|
-
|
|
1453
|
-
|
|
1454
|
-
|
|
1879
|
+
const emitImageAt = (x, topYUp, sink) => {
|
|
1880
|
+
sink.push({
|
|
1881
|
+
type: "image",
|
|
1882
|
+
x: pt(x),
|
|
1883
|
+
y: pt(asm.ctx.pageHeight - topYUp),
|
|
1884
|
+
width: pt(block.widthPt),
|
|
1885
|
+
height: pt(block.heightPt),
|
|
1886
|
+
imageResourceName: block.resourceName,
|
|
1887
|
+
...figId !== void 0 ? { structId: figId } : {}
|
|
1888
|
+
});
|
|
1889
|
+
};
|
|
1890
|
+
if (isOutOfFlowFloat(block.float)) {
|
|
1891
|
+
const fx = asm.floatX(block.float, block.widthPt);
|
|
1892
|
+
const fy = asm.floatTopYUp(block.float);
|
|
1893
|
+
emitImageAt(fx, fy, block.float.behind ? asm.floatsBehind : asm.floatsFront);
|
|
1894
|
+
if (block.float.wrap !== "none") asm.exclusions.push({
|
|
1895
|
+
x0: fx,
|
|
1896
|
+
x1: fx + block.widthPt,
|
|
1897
|
+
topYUp: fy,
|
|
1898
|
+
bottomYUp: fy - block.heightPt
|
|
1899
|
+
});
|
|
1900
|
+
} else {
|
|
1901
|
+
asm.cursorY -= block.spacingBeforePt;
|
|
1902
|
+
if (asm.cursorY - block.heightPt < asm.bottomLimit() && asm.colHasContent()) asm.advanceColumn();
|
|
1903
|
+
asm.cursorY -= block.heightPt;
|
|
1904
|
+
emitImageAt(asm.colLeft(), asm.cursorY + block.heightPt, asm.current);
|
|
1905
|
+
asm.cursorY -= block.spacingAfterPt;
|
|
1906
|
+
}
|
|
1455
1907
|
} else if (block.kind === "shape") {
|
|
1456
1908
|
const figId = builder ? createFigure(builder, block.altText, "Shape") : void 0;
|
|
1457
|
-
|
|
1458
|
-
|
|
1459
|
-
|
|
1460
|
-
|
|
1461
|
-
|
|
1462
|
-
|
|
1463
|
-
|
|
1464
|
-
|
|
1465
|
-
|
|
1466
|
-
|
|
1467
|
-
...
|
|
1468
|
-
|
|
1469
|
-
|
|
1470
|
-
|
|
1471
|
-
|
|
1472
|
-
|
|
1473
|
-
|
|
1474
|
-
|
|
1475
|
-
|
|
1476
|
-
|
|
1477
|
-
|
|
1478
|
-
|
|
1479
|
-
|
|
1480
|
-
|
|
1481
|
-
|
|
1482
|
-
|
|
1483
|
-
|
|
1484
|
-
|
|
1485
|
-
|
|
1486
|
-
|
|
1487
|
-
|
|
1488
|
-
|
|
1489
|
-
baselineY: pt(ctx.pageHeight - (textY + lineDescent(line))),
|
|
1490
|
-
...figId !== void 0 ? { structId: figId } : {}
|
|
1491
|
-
});
|
|
1909
|
+
const emitShapeAt = (x, bottomYUp, sink) => {
|
|
1910
|
+
const transform = flipTransform(buildShapeTransform(x, bottomYUp, block.widthPt, block.heightPt, block.rotation60k, block.flipH, block.flipV), asm.ctx.pageHeight);
|
|
1911
|
+
sink.push({
|
|
1912
|
+
type: "shape",
|
|
1913
|
+
shape: {
|
|
1914
|
+
paths: block.paths,
|
|
1915
|
+
...block.fillColorHex ? { fillColorHex: block.fillColorHex } : {},
|
|
1916
|
+
...block.stroke ? { stroke: block.stroke } : {},
|
|
1917
|
+
transform
|
|
1918
|
+
},
|
|
1919
|
+
...figId !== void 0 ? { structId: figId } : {}
|
|
1920
|
+
});
|
|
1921
|
+
if (block.textLines.length > 0) {
|
|
1922
|
+
const shapeBottom = bottomYUp;
|
|
1923
|
+
const shapeTop = bottomYUp + block.heightPt;
|
|
1924
|
+
const innerWidth = Math.max(1, block.widthPt - block.insetLeftPt - block.insetRightPt);
|
|
1925
|
+
let textY;
|
|
1926
|
+
if (block.anchor === "b") textY = shapeBottom + block.insetBottomPt + block.textHeightPt;
|
|
1927
|
+
else if (block.anchor === "ctr") textY = shapeBottom + (block.heightPt + block.textHeightPt) / 2;
|
|
1928
|
+
else textY = shapeTop - block.insetTopPt;
|
|
1929
|
+
for (const line of block.textLines) {
|
|
1930
|
+
const h = computeLineHeight(line, line.resolved);
|
|
1931
|
+
textY -= h;
|
|
1932
|
+
const lineOffset = alignmentOffset(line.resolved.alignment, line.contentWidthPt, innerWidth);
|
|
1933
|
+
sink.push({
|
|
1934
|
+
type: "line",
|
|
1935
|
+
line,
|
|
1936
|
+
originX: pt(x + block.insetLeftPt + lineOffset),
|
|
1937
|
+
baselineY: pt(asm.ctx.pageHeight - (textY + lineDescent(line))),
|
|
1938
|
+
...figId !== void 0 ? { structId: figId } : {}
|
|
1939
|
+
});
|
|
1940
|
+
}
|
|
1492
1941
|
}
|
|
1942
|
+
};
|
|
1943
|
+
if (isOutOfFlowFloat(block.float)) {
|
|
1944
|
+
const fx = asm.floatX(block.float, block.widthPt);
|
|
1945
|
+
const fy = asm.floatTopYUp(block.float);
|
|
1946
|
+
emitShapeAt(fx, fy - block.heightPt, block.float.behind ? asm.floatsBehind : asm.floatsFront);
|
|
1947
|
+
if (block.float.wrap !== "none") asm.exclusions.push({
|
|
1948
|
+
x0: fx,
|
|
1949
|
+
x1: fx + block.widthPt,
|
|
1950
|
+
topYUp: fy,
|
|
1951
|
+
bottomYUp: fy - block.heightPt
|
|
1952
|
+
});
|
|
1953
|
+
} else {
|
|
1954
|
+
asm.cursorY -= block.spacingBeforePt;
|
|
1955
|
+
if (asm.cursorY - block.heightPt < asm.bottomLimit() && asm.colHasContent()) asm.advanceColumn();
|
|
1956
|
+
asm.cursorY -= block.heightPt;
|
|
1957
|
+
const offset = alignmentOffset(block.resolvedAlignment, block.widthPt, asm.colWidth());
|
|
1958
|
+
emitShapeAt(asm.colLeft() + offset, asm.cursorY, asm.current);
|
|
1959
|
+
asm.cursorY -= block.spacingAfterPt;
|
|
1493
1960
|
}
|
|
1494
|
-
cursorY -= block.spacingAfterPt;
|
|
1495
1961
|
} else if (block.kind === "chart") {
|
|
1496
1962
|
const figId = builder ? createFigure(builder, block.altText, "Chart") : void 0;
|
|
1497
1963
|
const fig = figId !== void 0 ? { structId: figId } : {};
|
|
1498
|
-
|
|
1499
|
-
|
|
1500
|
-
|
|
1501
|
-
|
|
1502
|
-
|
|
1503
|
-
|
|
1504
|
-
|
|
1505
|
-
|
|
1506
|
-
|
|
1507
|
-
|
|
1508
|
-
|
|
1509
|
-
|
|
1510
|
-
|
|
1511
|
-
|
|
1512
|
-
|
|
1513
|
-
|
|
1514
|
-
|
|
1515
|
-
|
|
1516
|
-
|
|
1517
|
-
|
|
1518
|
-
|
|
1519
|
-
|
|
1520
|
-
|
|
1521
|
-
|
|
1522
|
-
|
|
1523
|
-
|
|
1524
|
-
|
|
1525
|
-
|
|
1526
|
-
|
|
1527
|
-
|
|
1528
|
-
|
|
1964
|
+
const emitChartAt = (x, bottomYUp, sink) => {
|
|
1965
|
+
for (const s of block.layout.shapes) sink.push({
|
|
1966
|
+
type: "shape",
|
|
1967
|
+
shape: {
|
|
1968
|
+
paths: s.paths,
|
|
1969
|
+
...s.fillColorHex ? { fillColorHex: s.fillColorHex } : {},
|
|
1970
|
+
...s.stroke ? { stroke: s.stroke } : {},
|
|
1971
|
+
transform: flipTransform([
|
|
1972
|
+
1,
|
|
1973
|
+
0,
|
|
1974
|
+
0,
|
|
1975
|
+
1,
|
|
1976
|
+
x,
|
|
1977
|
+
bottomYUp
|
|
1978
|
+
], asm.ctx.pageHeight)
|
|
1979
|
+
},
|
|
1980
|
+
...fig
|
|
1981
|
+
});
|
|
1982
|
+
for (const t of block.layout.texts) sink.push({
|
|
1983
|
+
type: "line",
|
|
1984
|
+
line: t.line,
|
|
1985
|
+
originX: pt(x + t.x),
|
|
1986
|
+
baselineY: pt(asm.ctx.pageHeight - (bottomYUp + t.y)),
|
|
1987
|
+
...fig
|
|
1988
|
+
});
|
|
1989
|
+
};
|
|
1990
|
+
if (isOutOfFlowFloat(block.float)) {
|
|
1991
|
+
const fx = asm.floatX(block.float, block.widthPt);
|
|
1992
|
+
const fy = asm.floatTopYUp(block.float);
|
|
1993
|
+
emitChartAt(fx, fy - block.heightPt, block.float.behind ? asm.floatsBehind : asm.floatsFront);
|
|
1994
|
+
if (block.float.wrap !== "none") asm.exclusions.push({
|
|
1995
|
+
x0: fx,
|
|
1996
|
+
x1: fx + block.widthPt,
|
|
1997
|
+
topYUp: fy,
|
|
1998
|
+
bottomYUp: fy - block.heightPt
|
|
1999
|
+
});
|
|
2000
|
+
} else {
|
|
2001
|
+
asm.cursorY -= block.spacingBeforePt;
|
|
2002
|
+
if (asm.cursorY - block.heightPt < asm.bottomLimit() && asm.colHasContent()) asm.advanceColumn();
|
|
2003
|
+
asm.cursorY -= block.heightPt;
|
|
2004
|
+
const offset = alignmentOffset(block.resolvedAlignment, block.widthPt, asm.colWidth());
|
|
2005
|
+
emitChartAt(asm.colLeft() + offset, asm.cursorY, asm.current);
|
|
2006
|
+
asm.cursorY -= block.spacingAfterPt;
|
|
2007
|
+
}
|
|
1529
2008
|
} else {
|
|
1530
2009
|
const colCount = block.rows.reduce((max, r) => Math.max(max, r.cells.reduce((s, c) => Math.max(s, c.colStart + c.colSpan), 0)), 0);
|
|
1531
2010
|
const headerRows = [];
|
|
@@ -1533,7 +2012,7 @@ function paginateSections(blocks, sectionCtxs, builder, defaultLang = "en-US") {
|
|
|
1533
2012
|
else break;
|
|
1534
2013
|
const headerHeightPt = headerRows.reduce((s, r) => s + r.heightPt, 0);
|
|
1535
2014
|
const tableNode = builder ? builder.create("Table", builder.root) : void 0;
|
|
1536
|
-
const tableX =
|
|
2015
|
+
const tableX = asm.colLeft() + block.xOffsetPt;
|
|
1537
2016
|
for (let ri = 0; ri < block.rows.length; ri++) {
|
|
1538
2017
|
const row = block.rows[ri];
|
|
1539
2018
|
const isLeadingHeader = ri < headerRows.length;
|
|
@@ -1551,27 +2030,34 @@ function paginateSections(blocks, sectionCtxs, builder, defaultLang = "en-US") {
|
|
|
1551
2030
|
return b.create("P", cellNode).id;
|
|
1552
2031
|
});
|
|
1553
2032
|
}
|
|
1554
|
-
const chunks = row.heightPt > ctx.pageContentHeight ? splitRowIntoChunks(row, ctx.pageContentHeight) : [row];
|
|
2033
|
+
const chunks = row.heightPt > asm.ctx.pageContentHeight ? splitRowIntoChunks(row, asm.ctx.pageContentHeight) : [row];
|
|
1555
2034
|
for (let ci = 0; ci < chunks.length; ci++) {
|
|
1556
2035
|
const chunk = chunks[ci];
|
|
1557
|
-
const forcedBreak = ci === 0 && row.breakBefore && !isLeadingHeader && current.length > 0;
|
|
1558
|
-
const overflow = cursorY - chunk.heightPt <
|
|
2036
|
+
const forcedBreak = ci === 0 && row.breakBefore && !isLeadingHeader && asm.current.length > 0;
|
|
2037
|
+
const overflow = asm.cursorY - chunk.heightPt < asm.bottomLimit() && asm.colHasContent();
|
|
1559
2038
|
if (forcedBreak || overflow) {
|
|
1560
|
-
flushPage();
|
|
1561
|
-
|
|
1562
|
-
|
|
1563
|
-
cursorY
|
|
2039
|
+
if (forcedBreak) asm.flushPage();
|
|
2040
|
+
else asm.advanceColumn();
|
|
2041
|
+
if (!isLeadingHeader && headerRows.length > 0 && asm.cursorY - headerHeightPt - chunk.heightPt >= asm.bottomLimit()) for (const hr of headerRows) {
|
|
2042
|
+
emitRowChunk(asm.current, hr, tableX, asm.cursorY, asm.ctx.pageHeight, colCount, void 0);
|
|
2043
|
+
asm.cursorY -= hr.heightPt;
|
|
1564
2044
|
}
|
|
1565
2045
|
}
|
|
1566
|
-
emitRowChunk(current, chunk, tableX, cursorY, ctx.pageHeight, colCount, cellStructIds);
|
|
1567
|
-
cursorY -= chunk.heightPt;
|
|
2046
|
+
emitRowChunk(asm.current, chunk, tableX, asm.cursorY, asm.ctx.pageHeight, colCount, cellStructIds);
|
|
2047
|
+
asm.cursorY -= chunk.heightPt;
|
|
1568
2048
|
}
|
|
1569
2049
|
}
|
|
1570
2050
|
}
|
|
1571
2051
|
}
|
|
1572
|
-
flushPage();
|
|
1573
|
-
if (pages.length === 0) flushPage(true);
|
|
1574
|
-
|
|
2052
|
+
asm.flushPage();
|
|
2053
|
+
if (asm.pages.length === 0) asm.flushPage(true);
|
|
2054
|
+
for (const d of asm.dynBands) {
|
|
2055
|
+
const cmds = d.render(d.pageNumber, asm.pages.length);
|
|
2056
|
+
const page = asm.pages[d.pageIdx];
|
|
2057
|
+
if (d.position === "header") page.commands.unshift(...cmds);
|
|
2058
|
+
else page.commands.push(...cmds);
|
|
2059
|
+
}
|
|
2060
|
+
return asm.pages;
|
|
1575
2061
|
}
|
|
1576
2062
|
function tableCellRowSpan(rows, startRowIdx, colStart) {
|
|
1577
2063
|
let span = 1;
|