pdfmake 0.3.0-beta.7 → 0.3.0-beta.8
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/CHANGELOG.md +4 -0
- package/build/pdfmake.js +2654 -2525
- package/build/pdfmake.js.map +1 -1
- package/build/pdfmake.min.js +2 -2
- package/build/pdfmake.min.js.map +1 -1
- package/package.json +1 -1
- package/js/3rd-party/svg-to-pdfkit/source.js +0 -3626
- package/js/3rd-party/svg-to-pdfkit.js +0 -7
- package/js/DocMeasure.js +0 -627
- package/js/DocPreprocessor.js +0 -238
- package/js/DocumentContext.js +0 -265
- package/js/ElementWriter.js +0 -331
- package/js/LayoutBuilder.js +0 -694
- package/js/Line.js +0 -105
- package/js/OutputDocument.js +0 -76
- package/js/OutputDocumentServer.js +0 -27
- package/js/PDFDocument.js +0 -144
- package/js/PageElementWriter.js +0 -140
- package/js/PageSize.js +0 -74
- package/js/Printer.js +0 -291
- package/js/Renderer.js +0 -375
- package/js/SVGMeasure.js +0 -69
- package/js/StyleContextStack.js +0 -180
- package/js/TableProcessor.js +0 -511
- package/js/TextBreaker.js +0 -139
- package/js/TextDecorator.js +0 -143
- package/js/TextInlines.js +0 -206
- package/js/URLResolver.js +0 -73
- package/js/base.js +0 -52
- package/js/browser-extensions/OutputDocumentBrowser.js +0 -118
- package/js/browser-extensions/URLBrowserResolver.js +0 -76
- package/js/browser-extensions/fonts/Roboto.js +0 -38
- package/js/browser-extensions/index.js +0 -53
- package/js/browser-extensions/pdfMake.js +0 -15
- package/js/browser-extensions/standard-fonts/Courier.js +0 -38
- package/js/browser-extensions/standard-fonts/Helvetica.js +0 -38
- package/js/browser-extensions/standard-fonts/Symbol.js +0 -23
- package/js/browser-extensions/standard-fonts/Times.js +0 -38
- package/js/browser-extensions/standard-fonts/ZapfDingbats.js +0 -23
- package/js/browser-extensions/virtual-fs-cjs.js +0 -3
- package/js/columnCalculator.js +0 -129
- package/js/helpers/node.js +0 -98
- package/js/helpers/tools.js +0 -40
- package/js/helpers/variableType.js +0 -47
- package/js/index.js +0 -15
- package/js/qrEnc.js +0 -721
- package/js/standardPageSizes.js +0 -56
- package/js/tableLayouts.js +0 -98
- package/js/virtual-fs.js +0 -60
package/js/LayoutBuilder.js
DELETED
|
@@ -1,694 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
exports.__esModule = true;
|
|
4
|
-
exports.default = void 0;
|
|
5
|
-
var _DocPreprocessor = _interopRequireDefault(require("./DocPreprocessor"));
|
|
6
|
-
var _DocMeasure = _interopRequireDefault(require("./DocMeasure"));
|
|
7
|
-
var _DocumentContext = _interopRequireDefault(require("./DocumentContext"));
|
|
8
|
-
var _PageElementWriter = _interopRequireDefault(require("./PageElementWriter"));
|
|
9
|
-
var _columnCalculator = _interopRequireDefault(require("./columnCalculator"));
|
|
10
|
-
var _TableProcessor = _interopRequireDefault(require("./TableProcessor"));
|
|
11
|
-
var _Line = _interopRequireDefault(require("./Line"));
|
|
12
|
-
var _variableType = require("./helpers/variableType");
|
|
13
|
-
var _node = require("./helpers/node");
|
|
14
|
-
var _tools = require("./helpers/tools");
|
|
15
|
-
var _TextInlines = _interopRequireDefault(require("./TextInlines"));
|
|
16
|
-
var _StyleContextStack = _interopRequireDefault(require("./StyleContextStack"));
|
|
17
|
-
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
18
|
-
function addAll(target, otherArray) {
|
|
19
|
-
otherArray.forEach(item => {
|
|
20
|
-
target.push(item);
|
|
21
|
-
});
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
/**
|
|
25
|
-
* Layout engine which turns document-definition-object into a set of pages, lines, inlines
|
|
26
|
-
* and vectors ready to be rendered into a PDF
|
|
27
|
-
*/
|
|
28
|
-
class LayoutBuilder {
|
|
29
|
-
/**
|
|
30
|
-
* @param {object} pageSize - an object defining page width and height
|
|
31
|
-
* @param {object} pageMargins - an object defining top, left, right and bottom margins
|
|
32
|
-
* @param {object} svgMeasure
|
|
33
|
-
*/
|
|
34
|
-
constructor(pageSize, pageMargins, svgMeasure) {
|
|
35
|
-
this.pageSize = pageSize;
|
|
36
|
-
this.pageMargins = pageMargins;
|
|
37
|
-
this.svgMeasure = svgMeasure;
|
|
38
|
-
this.tableLayouts = {};
|
|
39
|
-
}
|
|
40
|
-
registerTableLayouts(tableLayouts) {
|
|
41
|
-
this.tableLayouts = (0, _tools.pack)(this.tableLayouts, tableLayouts);
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
/**
|
|
45
|
-
* Executes layout engine on document-definition-object and creates an array of pages
|
|
46
|
-
* containing positioned Blocks, Lines and inlines
|
|
47
|
-
*
|
|
48
|
-
* @param {object} docStructure document-definition-object
|
|
49
|
-
* @param {object} pdfDocument pdfkit document
|
|
50
|
-
* @param {object} styleDictionary dictionary with style definitions
|
|
51
|
-
* @param {object} defaultStyle default style definition
|
|
52
|
-
* @param {object} background
|
|
53
|
-
* @param {object} header
|
|
54
|
-
* @param {object} footer
|
|
55
|
-
* @param {object} watermark
|
|
56
|
-
* @param {object} pageBreakBeforeFct
|
|
57
|
-
* @returns {Array} an array of pages
|
|
58
|
-
*/
|
|
59
|
-
layoutDocument(docStructure, pdfDocument, styleDictionary, defaultStyle, background, header, footer, watermark, pageBreakBeforeFct) {
|
|
60
|
-
function addPageBreaksIfNecessary(linearNodeList, pages) {
|
|
61
|
-
if (typeof pageBreakBeforeFct !== 'function') {
|
|
62
|
-
return false;
|
|
63
|
-
}
|
|
64
|
-
linearNodeList = linearNodeList.filter(node => node.positions.length > 0);
|
|
65
|
-
linearNodeList.forEach(node => {
|
|
66
|
-
let nodeInfo = {};
|
|
67
|
-
['id', 'text', 'ul', 'ol', 'table', 'image', 'qr', 'canvas', 'svg', 'columns', 'headlineLevel', 'style', 'pageBreak', 'pageOrientation', 'width', 'height'].forEach(key => {
|
|
68
|
-
if (node[key] !== undefined) {
|
|
69
|
-
nodeInfo[key] = node[key];
|
|
70
|
-
}
|
|
71
|
-
});
|
|
72
|
-
nodeInfo.startPosition = node.positions[0];
|
|
73
|
-
nodeInfo.pageNumbers = Array.from(new Set(node.positions.map(node => node.pageNumber)));
|
|
74
|
-
nodeInfo.pages = pages.length;
|
|
75
|
-
nodeInfo.stack = Array.isArray(node.stack);
|
|
76
|
-
node.nodeInfo = nodeInfo;
|
|
77
|
-
});
|
|
78
|
-
for (let index = 0; index < linearNodeList.length; index++) {
|
|
79
|
-
let node = linearNodeList[index];
|
|
80
|
-
if (node.pageBreak !== 'before' && !node.pageBreakCalculated) {
|
|
81
|
-
node.pageBreakCalculated = true;
|
|
82
|
-
let pageNumber = node.nodeInfo.pageNumbers[0];
|
|
83
|
-
if (pageBreakBeforeFct(node.nodeInfo, {
|
|
84
|
-
getFollowingNodesOnPage: () => {
|
|
85
|
-
let followingNodesOnPage = [];
|
|
86
|
-
for (let ii = index + 1, l = linearNodeList.length; ii < l; ii++) {
|
|
87
|
-
if (linearNodeList[ii].nodeInfo.pageNumbers.indexOf(pageNumber) > -1) {
|
|
88
|
-
followingNodesOnPage.push(linearNodeList[ii].nodeInfo);
|
|
89
|
-
}
|
|
90
|
-
}
|
|
91
|
-
return followingNodesOnPage;
|
|
92
|
-
},
|
|
93
|
-
getNodesOnNextPage: () => {
|
|
94
|
-
let nodesOnNextPage = [];
|
|
95
|
-
for (let ii = index + 1, l = linearNodeList.length; ii < l; ii++) {
|
|
96
|
-
if (linearNodeList[ii].nodeInfo.pageNumbers.indexOf(pageNumber + 1) > -1) {
|
|
97
|
-
nodesOnNextPage.push(linearNodeList[ii].nodeInfo);
|
|
98
|
-
}
|
|
99
|
-
}
|
|
100
|
-
return nodesOnNextPage;
|
|
101
|
-
},
|
|
102
|
-
getPreviousNodesOnPage: () => {
|
|
103
|
-
let previousNodesOnPage = [];
|
|
104
|
-
for (let ii = 0; ii < index; ii++) {
|
|
105
|
-
if (linearNodeList[ii].nodeInfo.pageNumbers.indexOf(pageNumber) > -1) {
|
|
106
|
-
previousNodesOnPage.push(linearNodeList[ii].nodeInfo);
|
|
107
|
-
}
|
|
108
|
-
}
|
|
109
|
-
return previousNodesOnPage;
|
|
110
|
-
}
|
|
111
|
-
})) {
|
|
112
|
-
node.pageBreak = 'before';
|
|
113
|
-
return true;
|
|
114
|
-
}
|
|
115
|
-
}
|
|
116
|
-
}
|
|
117
|
-
return false;
|
|
118
|
-
}
|
|
119
|
-
this.docPreprocessor = new _DocPreprocessor.default();
|
|
120
|
-
this.docMeasure = new _DocMeasure.default(pdfDocument, styleDictionary, defaultStyle, this.svgMeasure, this.tableLayouts);
|
|
121
|
-
function resetXYs(result) {
|
|
122
|
-
result.linearNodeList.forEach(node => {
|
|
123
|
-
node.resetXY();
|
|
124
|
-
});
|
|
125
|
-
}
|
|
126
|
-
let result = this.tryLayoutDocument(docStructure, pdfDocument, styleDictionary, defaultStyle, background, header, footer, watermark);
|
|
127
|
-
while (addPageBreaksIfNecessary(result.linearNodeList, result.pages)) {
|
|
128
|
-
resetXYs(result);
|
|
129
|
-
result = this.tryLayoutDocument(docStructure, pdfDocument, styleDictionary, defaultStyle, background, header, footer, watermark);
|
|
130
|
-
}
|
|
131
|
-
return result.pages;
|
|
132
|
-
}
|
|
133
|
-
tryLayoutDocument(docStructure, pdfDocument, styleDictionary, defaultStyle, background, header, footer, watermark) {
|
|
134
|
-
this.linearNodeList = [];
|
|
135
|
-
docStructure = this.docPreprocessor.preprocessDocument(docStructure);
|
|
136
|
-
docStructure = this.docMeasure.measureDocument(docStructure);
|
|
137
|
-
this.writer = new _PageElementWriter.default(new _DocumentContext.default(this.pageSize, this.pageMargins));
|
|
138
|
-
this.writer.context().addListener('pageAdded', () => {
|
|
139
|
-
this.addBackground(background);
|
|
140
|
-
});
|
|
141
|
-
this.addBackground(background);
|
|
142
|
-
this.processNode(docStructure);
|
|
143
|
-
this.addHeadersAndFooters(header, footer);
|
|
144
|
-
if (watermark != null) {
|
|
145
|
-
this.addWatermark(watermark, pdfDocument, defaultStyle);
|
|
146
|
-
}
|
|
147
|
-
return {
|
|
148
|
-
pages: this.writer.context().pages,
|
|
149
|
-
linearNodeList: this.linearNodeList
|
|
150
|
-
};
|
|
151
|
-
}
|
|
152
|
-
addBackground(background) {
|
|
153
|
-
let backgroundGetter = typeof background === 'function' ? background : () => background;
|
|
154
|
-
let context = this.writer.context();
|
|
155
|
-
let pageSize = context.getCurrentPage().pageSize;
|
|
156
|
-
let pageBackground = backgroundGetter(context.page + 1, pageSize);
|
|
157
|
-
if (pageBackground) {
|
|
158
|
-
this.writer.beginUnbreakableBlock(pageSize.width, pageSize.height);
|
|
159
|
-
pageBackground = this.docPreprocessor.preprocessDocument(pageBackground);
|
|
160
|
-
this.processNode(this.docMeasure.measureDocument(pageBackground));
|
|
161
|
-
this.writer.commitUnbreakableBlock(0, 0);
|
|
162
|
-
context.backgroundLength[context.page] += pageBackground.positions.length;
|
|
163
|
-
}
|
|
164
|
-
}
|
|
165
|
-
addStaticRepeatable(headerOrFooter, sizeFunction) {
|
|
166
|
-
this.addDynamicRepeatable(() =>
|
|
167
|
-
// copy to new object
|
|
168
|
-
JSON.parse(JSON.stringify(headerOrFooter)), sizeFunction);
|
|
169
|
-
}
|
|
170
|
-
addDynamicRepeatable(nodeGetter, sizeFunction) {
|
|
171
|
-
let pages = this.writer.context().pages;
|
|
172
|
-
for (let pageIndex = 0, l = pages.length; pageIndex < l; pageIndex++) {
|
|
173
|
-
this.writer.context().page = pageIndex;
|
|
174
|
-
let node = nodeGetter(pageIndex + 1, l, this.writer.context().pages[pageIndex].pageSize);
|
|
175
|
-
if (node) {
|
|
176
|
-
let sizes = sizeFunction(this.writer.context().getCurrentPage().pageSize, this.pageMargins);
|
|
177
|
-
this.writer.beginUnbreakableBlock(sizes.width, sizes.height);
|
|
178
|
-
node = this.docPreprocessor.preprocessDocument(node);
|
|
179
|
-
this.processNode(this.docMeasure.measureDocument(node));
|
|
180
|
-
this.writer.commitUnbreakableBlock(sizes.x, sizes.y);
|
|
181
|
-
}
|
|
182
|
-
}
|
|
183
|
-
}
|
|
184
|
-
addHeadersAndFooters(header, footer) {
|
|
185
|
-
const headerSizeFct = (pageSize, pageMargins) => ({
|
|
186
|
-
x: 0,
|
|
187
|
-
y: 0,
|
|
188
|
-
width: pageSize.width,
|
|
189
|
-
height: pageMargins.top
|
|
190
|
-
});
|
|
191
|
-
const footerSizeFct = (pageSize, pageMargins) => ({
|
|
192
|
-
x: 0,
|
|
193
|
-
y: pageSize.height - pageMargins.bottom,
|
|
194
|
-
width: pageSize.width,
|
|
195
|
-
height: pageMargins.bottom
|
|
196
|
-
});
|
|
197
|
-
if (typeof header === 'function') {
|
|
198
|
-
this.addDynamicRepeatable(header, headerSizeFct);
|
|
199
|
-
} else if (header) {
|
|
200
|
-
this.addStaticRepeatable(header, headerSizeFct);
|
|
201
|
-
}
|
|
202
|
-
if (typeof footer === 'function') {
|
|
203
|
-
this.addDynamicRepeatable(footer, footerSizeFct);
|
|
204
|
-
} else if (footer) {
|
|
205
|
-
this.addStaticRepeatable(footer, footerSizeFct);
|
|
206
|
-
}
|
|
207
|
-
}
|
|
208
|
-
addWatermark(watermark, pdfDocument, defaultStyle) {
|
|
209
|
-
if ((0, _variableType.isString)(watermark)) {
|
|
210
|
-
watermark = {
|
|
211
|
-
'text': watermark
|
|
212
|
-
};
|
|
213
|
-
}
|
|
214
|
-
if (!watermark.text) {
|
|
215
|
-
// empty watermark text
|
|
216
|
-
return;
|
|
217
|
-
}
|
|
218
|
-
watermark.font = watermark.font || defaultStyle.font || 'Roboto';
|
|
219
|
-
watermark.fontSize = watermark.fontSize || 'auto';
|
|
220
|
-
watermark.color = watermark.color || 'black';
|
|
221
|
-
watermark.opacity = (0, _variableType.isNumber)(watermark.opacity) ? watermark.opacity : 0.6;
|
|
222
|
-
watermark.bold = watermark.bold || false;
|
|
223
|
-
watermark.italics = watermark.italics || false;
|
|
224
|
-
watermark.angle = (0, _variableType.isValue)(watermark.angle) ? watermark.angle : null;
|
|
225
|
-
if (watermark.angle === null) {
|
|
226
|
-
watermark.angle = Math.atan2(this.pageSize.height, this.pageSize.width) * -180 / Math.PI;
|
|
227
|
-
}
|
|
228
|
-
if (watermark.fontSize === 'auto') {
|
|
229
|
-
watermark.fontSize = getWatermarkFontSize(this.pageSize, watermark, pdfDocument);
|
|
230
|
-
}
|
|
231
|
-
let watermarkObject = {
|
|
232
|
-
text: watermark.text,
|
|
233
|
-
font: pdfDocument.provideFont(watermark.font, watermark.bold, watermark.italics),
|
|
234
|
-
fontSize: watermark.fontSize,
|
|
235
|
-
color: watermark.color,
|
|
236
|
-
opacity: watermark.opacity,
|
|
237
|
-
angle: watermark.angle
|
|
238
|
-
};
|
|
239
|
-
watermarkObject._size = getWatermarkSize(watermark, pdfDocument);
|
|
240
|
-
let pages = this.writer.context().pages;
|
|
241
|
-
for (let i = 0, l = pages.length; i < l; i++) {
|
|
242
|
-
pages[i].watermark = watermarkObject;
|
|
243
|
-
}
|
|
244
|
-
function getWatermarkSize(watermark, pdfDocument) {
|
|
245
|
-
let textInlines = new _TextInlines.default(pdfDocument);
|
|
246
|
-
let styleContextStack = new _StyleContextStack.default(null, {
|
|
247
|
-
font: watermark.font,
|
|
248
|
-
bold: watermark.bold,
|
|
249
|
-
italics: watermark.italics
|
|
250
|
-
});
|
|
251
|
-
styleContextStack.push({
|
|
252
|
-
fontSize: watermark.fontSize
|
|
253
|
-
});
|
|
254
|
-
let size = textInlines.sizeOfText(watermark.text, styleContextStack);
|
|
255
|
-
let rotatedSize = textInlines.sizeOfRotatedText(watermark.text, watermark.angle, styleContextStack);
|
|
256
|
-
return {
|
|
257
|
-
size: size,
|
|
258
|
-
rotatedSize: rotatedSize
|
|
259
|
-
};
|
|
260
|
-
}
|
|
261
|
-
function getWatermarkFontSize(pageSize, watermark, pdfDocument) {
|
|
262
|
-
let textInlines = new _TextInlines.default(pdfDocument);
|
|
263
|
-
let styleContextStack = new _StyleContextStack.default(null, {
|
|
264
|
-
font: watermark.font,
|
|
265
|
-
bold: watermark.bold,
|
|
266
|
-
italics: watermark.italics
|
|
267
|
-
});
|
|
268
|
-
let rotatedSize;
|
|
269
|
-
|
|
270
|
-
/**
|
|
271
|
-
* Binary search the best font size.
|
|
272
|
-
* Initial bounds [0, 1000]
|
|
273
|
-
* Break when range < 1
|
|
274
|
-
*/
|
|
275
|
-
let a = 0;
|
|
276
|
-
let b = 1000;
|
|
277
|
-
let c = (a + b) / 2;
|
|
278
|
-
while (Math.abs(a - b) > 1) {
|
|
279
|
-
styleContextStack.push({
|
|
280
|
-
fontSize: c
|
|
281
|
-
});
|
|
282
|
-
rotatedSize = textInlines.sizeOfRotatedText(watermark.text, watermark.angle, styleContextStack);
|
|
283
|
-
if (rotatedSize.width > pageSize.width) {
|
|
284
|
-
b = c;
|
|
285
|
-
c = (a + b) / 2;
|
|
286
|
-
} else if (rotatedSize.width < pageSize.width) {
|
|
287
|
-
if (rotatedSize.height > pageSize.height) {
|
|
288
|
-
b = c;
|
|
289
|
-
c = (a + b) / 2;
|
|
290
|
-
} else {
|
|
291
|
-
a = c;
|
|
292
|
-
c = (a + b) / 2;
|
|
293
|
-
}
|
|
294
|
-
}
|
|
295
|
-
styleContextStack.pop();
|
|
296
|
-
}
|
|
297
|
-
/*
|
|
298
|
-
End binary search
|
|
299
|
-
*/
|
|
300
|
-
return c;
|
|
301
|
-
}
|
|
302
|
-
}
|
|
303
|
-
processNode(node) {
|
|
304
|
-
const applyMargins = callback => {
|
|
305
|
-
let margin = node._margin;
|
|
306
|
-
if (node.pageBreak === 'before') {
|
|
307
|
-
this.writer.moveToNextPage(node.pageOrientation);
|
|
308
|
-
} else if (node.pageBreak === 'beforeOdd') {
|
|
309
|
-
this.writer.moveToNextPage(node.pageOrientation);
|
|
310
|
-
if ((this.writer.context().page + 1) % 2 === 1) {
|
|
311
|
-
this.writer.moveToNextPage(node.pageOrientation);
|
|
312
|
-
}
|
|
313
|
-
} else if (node.pageBreak === 'beforeEven') {
|
|
314
|
-
this.writer.moveToNextPage(node.pageOrientation);
|
|
315
|
-
if ((this.writer.context().page + 1) % 2 === 0) {
|
|
316
|
-
this.writer.moveToNextPage(node.pageOrientation);
|
|
317
|
-
}
|
|
318
|
-
}
|
|
319
|
-
if (margin) {
|
|
320
|
-
this.writer.context().moveDown(margin[1]);
|
|
321
|
-
this.writer.context().addMargin(margin[0], margin[2]);
|
|
322
|
-
}
|
|
323
|
-
callback();
|
|
324
|
-
if (margin) {
|
|
325
|
-
this.writer.context().addMargin(-margin[0], -margin[2]);
|
|
326
|
-
this.writer.context().moveDown(margin[3]);
|
|
327
|
-
}
|
|
328
|
-
if (node.pageBreak === 'after') {
|
|
329
|
-
this.writer.moveToNextPage(node.pageOrientation);
|
|
330
|
-
} else if (node.pageBreak === 'afterOdd') {
|
|
331
|
-
this.writer.moveToNextPage(node.pageOrientation);
|
|
332
|
-
if ((this.writer.context().page + 1) % 2 === 1) {
|
|
333
|
-
this.writer.moveToNextPage(node.pageOrientation);
|
|
334
|
-
}
|
|
335
|
-
} else if (node.pageBreak === 'afterEven') {
|
|
336
|
-
this.writer.moveToNextPage(node.pageOrientation);
|
|
337
|
-
if ((this.writer.context().page + 1) % 2 === 0) {
|
|
338
|
-
this.writer.moveToNextPage(node.pageOrientation);
|
|
339
|
-
}
|
|
340
|
-
}
|
|
341
|
-
};
|
|
342
|
-
this.linearNodeList.push(node);
|
|
343
|
-
decorateNode(node);
|
|
344
|
-
applyMargins(() => {
|
|
345
|
-
let unbreakable = node.unbreakable;
|
|
346
|
-
if (unbreakable) {
|
|
347
|
-
this.writer.beginUnbreakableBlock();
|
|
348
|
-
}
|
|
349
|
-
let absPosition = node.absolutePosition;
|
|
350
|
-
if (absPosition) {
|
|
351
|
-
this.writer.context().beginDetachedBlock();
|
|
352
|
-
this.writer.context().moveTo(absPosition.x || 0, absPosition.y || 0);
|
|
353
|
-
}
|
|
354
|
-
let relPosition = node.relativePosition;
|
|
355
|
-
if (relPosition) {
|
|
356
|
-
this.writer.context().beginDetachedBlock();
|
|
357
|
-
this.writer.context().moveToRelative(relPosition.x || 0, relPosition.y || 0);
|
|
358
|
-
}
|
|
359
|
-
if (node.stack) {
|
|
360
|
-
this.processVerticalContainer(node);
|
|
361
|
-
} else if (node.columns) {
|
|
362
|
-
this.processColumns(node);
|
|
363
|
-
} else if (node.ul) {
|
|
364
|
-
this.processList(false, node);
|
|
365
|
-
} else if (node.ol) {
|
|
366
|
-
this.processList(true, node);
|
|
367
|
-
} else if (node.table) {
|
|
368
|
-
this.processTable(node);
|
|
369
|
-
} else if (node.text !== undefined) {
|
|
370
|
-
this.processLeaf(node);
|
|
371
|
-
} else if (node.toc) {
|
|
372
|
-
this.processToc(node);
|
|
373
|
-
} else if (node.image) {
|
|
374
|
-
this.processImage(node);
|
|
375
|
-
} else if (node.svg) {
|
|
376
|
-
this.processSVG(node);
|
|
377
|
-
} else if (node.canvas) {
|
|
378
|
-
this.processCanvas(node);
|
|
379
|
-
} else if (node.qr) {
|
|
380
|
-
this.processQr(node);
|
|
381
|
-
} else if (node.attachment) {
|
|
382
|
-
this.processAttachment(node);
|
|
383
|
-
} else if (!node._span) {
|
|
384
|
-
throw new Error(`Unrecognized document structure: ${(0, _node.stringifyNode)(node)}`);
|
|
385
|
-
}
|
|
386
|
-
if (absPosition || relPosition) {
|
|
387
|
-
this.writer.context().endDetachedBlock();
|
|
388
|
-
}
|
|
389
|
-
if (unbreakable) {
|
|
390
|
-
this.writer.commitUnbreakableBlock();
|
|
391
|
-
}
|
|
392
|
-
});
|
|
393
|
-
}
|
|
394
|
-
|
|
395
|
-
// vertical container
|
|
396
|
-
processVerticalContainer(node) {
|
|
397
|
-
node.stack.forEach(item => {
|
|
398
|
-
this.processNode(item);
|
|
399
|
-
addAll(node.positions, item.positions);
|
|
400
|
-
|
|
401
|
-
//TODO: paragraph gap
|
|
402
|
-
}, this);
|
|
403
|
-
}
|
|
404
|
-
|
|
405
|
-
// columns
|
|
406
|
-
processColumns(columnNode) {
|
|
407
|
-
let columns = columnNode.columns;
|
|
408
|
-
let availableWidth = this.writer.context().availableWidth;
|
|
409
|
-
let gaps = gapArray(columnNode._gap);
|
|
410
|
-
if (gaps) {
|
|
411
|
-
availableWidth -= (gaps.length - 1) * columnNode._gap;
|
|
412
|
-
}
|
|
413
|
-
_columnCalculator.default.buildColumnWidths(columns, availableWidth);
|
|
414
|
-
let result = this.processRow(columns, columns, gaps);
|
|
415
|
-
addAll(columnNode.positions, result.positions);
|
|
416
|
-
function gapArray(gap) {
|
|
417
|
-
if (!gap) {
|
|
418
|
-
return null;
|
|
419
|
-
}
|
|
420
|
-
let gaps = [];
|
|
421
|
-
gaps.push(0);
|
|
422
|
-
for (let i = columns.length - 1; i > 0; i--) {
|
|
423
|
-
gaps.push(gap);
|
|
424
|
-
}
|
|
425
|
-
return gaps;
|
|
426
|
-
}
|
|
427
|
-
}
|
|
428
|
-
processRow(columns, widths, gaps, tableBody, tableRow, height) {
|
|
429
|
-
const storePageBreakData = data => {
|
|
430
|
-
let pageDesc;
|
|
431
|
-
for (let i = 0, l = pageBreaks.length; i < l; i++) {
|
|
432
|
-
let desc = pageBreaks[i];
|
|
433
|
-
if (desc.prevPage === data.prevPage) {
|
|
434
|
-
pageDesc = desc;
|
|
435
|
-
break;
|
|
436
|
-
}
|
|
437
|
-
}
|
|
438
|
-
if (!pageDesc) {
|
|
439
|
-
pageDesc = data;
|
|
440
|
-
pageBreaks.push(pageDesc);
|
|
441
|
-
}
|
|
442
|
-
pageDesc.prevY = Math.max(pageDesc.prevY, data.prevY);
|
|
443
|
-
pageDesc.y = Math.min(pageDesc.y, data.y);
|
|
444
|
-
};
|
|
445
|
-
let pageBreaks = [];
|
|
446
|
-
let positions = [];
|
|
447
|
-
this.writer.addListener('pageChanged', storePageBreakData);
|
|
448
|
-
widths = widths || columns;
|
|
449
|
-
this.writer.context().beginColumnGroup();
|
|
450
|
-
for (let i = 0, l = columns.length; i < l; i++) {
|
|
451
|
-
let column = columns[i];
|
|
452
|
-
let width = widths[i]._calcWidth;
|
|
453
|
-
let leftOffset = colLeftOffset(i);
|
|
454
|
-
if (column.colSpan && column.colSpan > 1) {
|
|
455
|
-
for (let j = 1; j < column.colSpan; j++) {
|
|
456
|
-
width += widths[++i]._calcWidth + gaps[i];
|
|
457
|
-
}
|
|
458
|
-
}
|
|
459
|
-
this.writer.context().beginColumn(width, leftOffset, getEndingCell(column, i));
|
|
460
|
-
if (!column._span) {
|
|
461
|
-
this.processNode(column);
|
|
462
|
-
addAll(positions, column.positions);
|
|
463
|
-
} else if (column._columnEndingContext) {
|
|
464
|
-
// row-span ending
|
|
465
|
-
this.writer.context().markEnding(column);
|
|
466
|
-
}
|
|
467
|
-
}
|
|
468
|
-
this.writer.context().completeColumnGroup(height);
|
|
469
|
-
this.writer.removeListener('pageChanged', storePageBreakData);
|
|
470
|
-
return {
|
|
471
|
-
pageBreaks: pageBreaks,
|
|
472
|
-
positions: positions
|
|
473
|
-
};
|
|
474
|
-
function colLeftOffset(i) {
|
|
475
|
-
if (gaps && gaps.length > i) {
|
|
476
|
-
return gaps[i];
|
|
477
|
-
}
|
|
478
|
-
return 0;
|
|
479
|
-
}
|
|
480
|
-
function getEndingCell(column, columnIndex) {
|
|
481
|
-
if (column.rowSpan && column.rowSpan > 1) {
|
|
482
|
-
let endingRow = tableRow + column.rowSpan - 1;
|
|
483
|
-
if (endingRow >= tableBody.length) {
|
|
484
|
-
throw new Error(`Row span for column ${columnIndex} (with indexes starting from 0) exceeded row count`);
|
|
485
|
-
}
|
|
486
|
-
return tableBody[endingRow][columnIndex];
|
|
487
|
-
}
|
|
488
|
-
return null;
|
|
489
|
-
}
|
|
490
|
-
}
|
|
491
|
-
|
|
492
|
-
// lists
|
|
493
|
-
processList(orderedList, node) {
|
|
494
|
-
const addMarkerToFirstLeaf = line => {
|
|
495
|
-
// I'm not very happy with the way list processing is implemented
|
|
496
|
-
// (both code and algorithm should be rethinked)
|
|
497
|
-
if (nextMarker) {
|
|
498
|
-
let marker = nextMarker;
|
|
499
|
-
nextMarker = null;
|
|
500
|
-
if (marker.canvas) {
|
|
501
|
-
let vector = marker.canvas[0];
|
|
502
|
-
(0, _tools.offsetVector)(vector, -marker._minWidth, 0);
|
|
503
|
-
this.writer.addVector(vector);
|
|
504
|
-
} else if (marker._inlines) {
|
|
505
|
-
let markerLine = new _Line.default(this.pageSize.width);
|
|
506
|
-
markerLine.addInline(marker._inlines[0]);
|
|
507
|
-
markerLine.x = -marker._minWidth;
|
|
508
|
-
markerLine.y = line.getAscenderHeight() - markerLine.getAscenderHeight();
|
|
509
|
-
this.writer.addLine(markerLine, true);
|
|
510
|
-
}
|
|
511
|
-
}
|
|
512
|
-
};
|
|
513
|
-
let items = orderedList ? node.ol : node.ul;
|
|
514
|
-
let gapSize = node._gapSize;
|
|
515
|
-
this.writer.context().addMargin(gapSize.width);
|
|
516
|
-
let nextMarker;
|
|
517
|
-
this.writer.addListener('lineAdded', addMarkerToFirstLeaf);
|
|
518
|
-
items.forEach(item => {
|
|
519
|
-
nextMarker = item.listMarker;
|
|
520
|
-
this.processNode(item);
|
|
521
|
-
addAll(node.positions, item.positions);
|
|
522
|
-
});
|
|
523
|
-
this.writer.removeListener('lineAdded', addMarkerToFirstLeaf);
|
|
524
|
-
this.writer.context().addMargin(-gapSize.width);
|
|
525
|
-
}
|
|
526
|
-
|
|
527
|
-
// tables
|
|
528
|
-
processTable(tableNode) {
|
|
529
|
-
let processor = new _TableProcessor.default(tableNode);
|
|
530
|
-
processor.beginTable(this.writer);
|
|
531
|
-
let rowHeights = tableNode.table.heights;
|
|
532
|
-
for (let i = 0, l = tableNode.table.body.length; i < l; i++) {
|
|
533
|
-
processor.beginRow(i, this.writer);
|
|
534
|
-
let height;
|
|
535
|
-
if (typeof rowHeights === 'function') {
|
|
536
|
-
height = rowHeights(i);
|
|
537
|
-
} else if (Array.isArray(rowHeights)) {
|
|
538
|
-
height = rowHeights[i];
|
|
539
|
-
} else {
|
|
540
|
-
height = rowHeights;
|
|
541
|
-
}
|
|
542
|
-
if (height === 'auto') {
|
|
543
|
-
height = undefined;
|
|
544
|
-
}
|
|
545
|
-
let result = this.processRow(tableNode.table.body[i], tableNode.table.widths, tableNode._offsets.offsets, tableNode.table.body, i, height);
|
|
546
|
-
addAll(tableNode.positions, result.positions);
|
|
547
|
-
processor.endRow(i, this.writer, result.pageBreaks);
|
|
548
|
-
}
|
|
549
|
-
processor.endTable(this.writer);
|
|
550
|
-
}
|
|
551
|
-
|
|
552
|
-
// leafs (texts)
|
|
553
|
-
processLeaf(node) {
|
|
554
|
-
let line = this.buildNextLine(node);
|
|
555
|
-
if (line && (node.tocItem || node.id)) {
|
|
556
|
-
line._node = node;
|
|
557
|
-
}
|
|
558
|
-
let currentHeight = line ? line.getHeight() : 0;
|
|
559
|
-
let maxHeight = node.maxHeight || -1;
|
|
560
|
-
if (line) {
|
|
561
|
-
let nodeId = (0, _node.getNodeId)(node);
|
|
562
|
-
if (nodeId) {
|
|
563
|
-
line.id = nodeId;
|
|
564
|
-
}
|
|
565
|
-
}
|
|
566
|
-
if (node._tocItemRef) {
|
|
567
|
-
line._pageNodeRef = node._tocItemRef;
|
|
568
|
-
}
|
|
569
|
-
if (node._pageRef) {
|
|
570
|
-
line._pageNodeRef = node._pageRef._nodeRef;
|
|
571
|
-
}
|
|
572
|
-
if (line && line.inlines && Array.isArray(line.inlines)) {
|
|
573
|
-
for (let i = 0, l = line.inlines.length; i < l; i++) {
|
|
574
|
-
if (line.inlines[i]._tocItemRef) {
|
|
575
|
-
line.inlines[i]._pageNodeRef = line.inlines[i]._tocItemRef;
|
|
576
|
-
}
|
|
577
|
-
if (line.inlines[i]._pageRef) {
|
|
578
|
-
line.inlines[i]._pageNodeRef = line.inlines[i]._pageRef._nodeRef;
|
|
579
|
-
}
|
|
580
|
-
}
|
|
581
|
-
}
|
|
582
|
-
while (line && (maxHeight === -1 || currentHeight < maxHeight)) {
|
|
583
|
-
let positions = this.writer.addLine(line);
|
|
584
|
-
node.positions.push(positions);
|
|
585
|
-
line = this.buildNextLine(node);
|
|
586
|
-
if (line) {
|
|
587
|
-
currentHeight += line.getHeight();
|
|
588
|
-
}
|
|
589
|
-
}
|
|
590
|
-
}
|
|
591
|
-
processToc(node) {
|
|
592
|
-
if (node.toc.title) {
|
|
593
|
-
this.processNode(node.toc.title);
|
|
594
|
-
}
|
|
595
|
-
if (node.toc._table) {
|
|
596
|
-
this.processNode(node.toc._table);
|
|
597
|
-
}
|
|
598
|
-
}
|
|
599
|
-
buildNextLine(textNode) {
|
|
600
|
-
function cloneInline(inline) {
|
|
601
|
-
let newInline = inline.constructor();
|
|
602
|
-
for (let key in inline) {
|
|
603
|
-
newInline[key] = inline[key];
|
|
604
|
-
}
|
|
605
|
-
return newInline;
|
|
606
|
-
}
|
|
607
|
-
if (!textNode._inlines || textNode._inlines.length === 0) {
|
|
608
|
-
return null;
|
|
609
|
-
}
|
|
610
|
-
let line = new _Line.default(this.writer.context().availableWidth);
|
|
611
|
-
const textInlines = new _TextInlines.default(null);
|
|
612
|
-
let isForceContinue = false;
|
|
613
|
-
while (textNode._inlines && textNode._inlines.length > 0 && (line.hasEnoughSpaceForInline(textNode._inlines[0], textNode._inlines.slice(1)) || isForceContinue)) {
|
|
614
|
-
let isHardWrap = false;
|
|
615
|
-
let inline = textNode._inlines.shift();
|
|
616
|
-
isForceContinue = false;
|
|
617
|
-
if (!inline.noWrap && inline.text.length > 1 && inline.width > line.getAvailableWidth()) {
|
|
618
|
-
let widthPerChar = inline.width / inline.text.length;
|
|
619
|
-
let maxChars = Math.floor(line.getAvailableWidth() / widthPerChar);
|
|
620
|
-
if (maxChars < 1) {
|
|
621
|
-
maxChars = 1;
|
|
622
|
-
}
|
|
623
|
-
if (maxChars < inline.text.length) {
|
|
624
|
-
let newInline = cloneInline(inline);
|
|
625
|
-
newInline.text = inline.text.substr(maxChars);
|
|
626
|
-
inline.text = inline.text.substr(0, maxChars);
|
|
627
|
-
newInline.width = textInlines.widthOfText(newInline.text, newInline);
|
|
628
|
-
inline.width = textInlines.widthOfText(inline.text, inline);
|
|
629
|
-
textNode._inlines.unshift(newInline);
|
|
630
|
-
isHardWrap = true;
|
|
631
|
-
}
|
|
632
|
-
}
|
|
633
|
-
line.addInline(inline);
|
|
634
|
-
isForceContinue = inline.noNewLine && !isHardWrap;
|
|
635
|
-
}
|
|
636
|
-
line.lastLineInParagraph = textNode._inlines.length === 0;
|
|
637
|
-
return line;
|
|
638
|
-
}
|
|
639
|
-
|
|
640
|
-
// images
|
|
641
|
-
processImage(node) {
|
|
642
|
-
let position = this.writer.addImage(node);
|
|
643
|
-
node.positions.push(position);
|
|
644
|
-
}
|
|
645
|
-
processCanvas(node) {
|
|
646
|
-
let positions = this.writer.addCanvas(node);
|
|
647
|
-
addAll(node.positions, positions);
|
|
648
|
-
}
|
|
649
|
-
processSVG(node) {
|
|
650
|
-
let position = this.writer.addSVG(node);
|
|
651
|
-
node.positions.push(position);
|
|
652
|
-
}
|
|
653
|
-
processQr(node) {
|
|
654
|
-
let position = this.writer.addQr(node);
|
|
655
|
-
node.positions.push(position);
|
|
656
|
-
}
|
|
657
|
-
processAttachment(node) {
|
|
658
|
-
let position = this.writer.addAttachment(node);
|
|
659
|
-
node.positions.push(position);
|
|
660
|
-
}
|
|
661
|
-
}
|
|
662
|
-
function decorateNode(node) {
|
|
663
|
-
let x = node.x;
|
|
664
|
-
let y = node.y;
|
|
665
|
-
node.positions = [];
|
|
666
|
-
if (Array.isArray(node.canvas)) {
|
|
667
|
-
node.canvas.forEach(vector => {
|
|
668
|
-
let x = vector.x;
|
|
669
|
-
let y = vector.y;
|
|
670
|
-
let x1 = vector.x1;
|
|
671
|
-
let y1 = vector.y1;
|
|
672
|
-
let x2 = vector.x2;
|
|
673
|
-
let y2 = vector.y2;
|
|
674
|
-
vector.resetXY = () => {
|
|
675
|
-
vector.x = x;
|
|
676
|
-
vector.y = y;
|
|
677
|
-
vector.x1 = x1;
|
|
678
|
-
vector.y1 = y1;
|
|
679
|
-
vector.x2 = x2;
|
|
680
|
-
vector.y2 = y2;
|
|
681
|
-
};
|
|
682
|
-
});
|
|
683
|
-
}
|
|
684
|
-
node.resetXY = () => {
|
|
685
|
-
node.x = x;
|
|
686
|
-
node.y = y;
|
|
687
|
-
if (Array.isArray(node.canvas)) {
|
|
688
|
-
node.canvas.forEach(vector => {
|
|
689
|
-
vector.resetXY();
|
|
690
|
-
});
|
|
691
|
-
}
|
|
692
|
-
};
|
|
693
|
-
}
|
|
694
|
-
var _default = exports.default = LayoutBuilder;
|