pdfmake 0.3.0-beta.11 → 0.3.0-beta.13
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 +18 -2
- package/build/pdfmake.js +26384 -25999
- package/build/pdfmake.js.map +1 -1
- package/build/pdfmake.min.js +2 -2
- package/build/pdfmake.min.js.map +1 -1
- package/build/vfs_fonts.js +2 -1
- package/js/DocMeasure.js +9 -0
- package/js/DocumentContext.js +25 -9
- package/js/ElementWriter.js +12 -3
- package/js/LayoutBuilder.js +239 -118
- package/js/PageElementWriter.js +15 -0
- package/js/Printer.js +13 -0
- package/js/Renderer.js +22 -14
- package/js/SVGMeasure.js +2 -2
- package/js/TextInlines.js +1 -1
- package/js/URLResolver.js +3 -0
- package/js/helpers/tools.js +6 -0
- package/package.json +14 -14
- package/src/DocMeasure.js +8 -0
- package/src/DocumentContext.js +26 -12
- package/src/ElementWriter.js +11 -2
- package/src/LayoutBuilder.js +250 -119
- package/src/PageElementWriter.js +19 -0
- package/src/Printer.js +15 -0
- package/src/Renderer.js +13 -15
- package/src/SVGMeasure.js +2 -2
- package/src/TextInlines.js +1 -1
- package/src/URLResolver.js +4 -0
- package/src/helpers/tools.js +5 -0
- package/standard-fonts/Helvetica.js +0 -1
- package/.idea/workspace.xml +0 -20
- package/eslint.config.mjs +0 -52
package/js/Printer.js
CHANGED
|
@@ -9,6 +9,7 @@ var _PageSize = require("./PageSize");
|
|
|
9
9
|
var _tableLayouts = require("./tableLayouts");
|
|
10
10
|
var _Renderer = _interopRequireDefault(require("./Renderer"));
|
|
11
11
|
var _variableType = require("./helpers/variableType");
|
|
12
|
+
var _tools = require("./helpers/tools");
|
|
12
13
|
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
13
14
|
/**
|
|
14
15
|
* Printer which turns document definition into a pdf
|
|
@@ -50,15 +51,27 @@ class PdfPrinter {
|
|
|
50
51
|
this.resolveUrls(docDefinition).then(() => {
|
|
51
52
|
try {
|
|
52
53
|
docDefinition.version = docDefinition.version || '1.3';
|
|
54
|
+
docDefinition.subset = docDefinition.subset || undefined;
|
|
55
|
+
docDefinition.tagged = typeof docDefinition.tagged === 'boolean' ? docDefinition.tagged : false;
|
|
56
|
+
docDefinition.displayTitle = typeof docDefinition.displayTitle === 'boolean' ? docDefinition.displayTitle : false;
|
|
53
57
|
docDefinition.compress = typeof docDefinition.compress === 'boolean' ? docDefinition.compress : true;
|
|
54
58
|
docDefinition.images = docDefinition.images || {};
|
|
55
59
|
docDefinition.attachments = docDefinition.attachments || {};
|
|
56
60
|
docDefinition.pageMargins = (0, _variableType.isValue)(docDefinition.pageMargins) ? docDefinition.pageMargins : 40;
|
|
57
61
|
docDefinition.patterns = docDefinition.patterns || {};
|
|
62
|
+
if (docDefinition.header && typeof docDefinition.header !== 'function') {
|
|
63
|
+
docDefinition.header = (0, _tools.convertToDynamicContent)(docDefinition.header);
|
|
64
|
+
}
|
|
65
|
+
if (docDefinition.footer && typeof docDefinition.footer !== 'function') {
|
|
66
|
+
docDefinition.footer = (0, _tools.convertToDynamicContent)(docDefinition.footer);
|
|
67
|
+
}
|
|
58
68
|
let pageSize = (0, _PageSize.normalizePageSize)(docDefinition.pageSize, docDefinition.pageOrientation);
|
|
59
69
|
let pdfOptions = {
|
|
60
70
|
size: [pageSize.width, pageSize.height],
|
|
61
71
|
pdfVersion: docDefinition.version,
|
|
72
|
+
subset: docDefinition.subset,
|
|
73
|
+
tagged: docDefinition.tagged,
|
|
74
|
+
displayTitle: docDefinition.displayTitle,
|
|
62
75
|
compress: docDefinition.compress,
|
|
63
76
|
userPassword: docDefinition.userPassword,
|
|
64
77
|
ownerPassword: docDefinition.ownerPassword,
|
package/js/Renderer.js
CHANGED
|
@@ -29,7 +29,7 @@ const findFont = (fonts, requiredFonts, defaultFont) => {
|
|
|
29
29
|
* @returns {number}
|
|
30
30
|
*/
|
|
31
31
|
const offsetText = (y, inline) => {
|
|
32
|
-
|
|
32
|
+
let newY = y;
|
|
33
33
|
if (inline.sup) {
|
|
34
34
|
newY -= inline.fontSize * 0.75;
|
|
35
35
|
}
|
|
@@ -45,7 +45,7 @@ class Renderer {
|
|
|
45
45
|
}
|
|
46
46
|
renderPages(pages) {
|
|
47
47
|
this.pdfDocument._pdfMakePages = pages; // TODO: Why?
|
|
48
|
-
|
|
48
|
+
|
|
49
49
|
let totalItems = 0;
|
|
50
50
|
if (this.progressCallback) {
|
|
51
51
|
pages.forEach(page => {
|
|
@@ -54,10 +54,9 @@ class Renderer {
|
|
|
54
54
|
}
|
|
55
55
|
let renderedItems = 0;
|
|
56
56
|
for (let i = 0; i < pages.length; i++) {
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
}
|
|
57
|
+
this.pdfDocument.addPage({
|
|
58
|
+
size: [pages[i].pageSize.width, pages[i].pageSize.height]
|
|
59
|
+
});
|
|
61
60
|
let page = pages[i];
|
|
62
61
|
for (let ii = 0, il = page.items.length; ii < il; ii++) {
|
|
63
62
|
let item = page.items[ii];
|
|
@@ -329,6 +328,23 @@ class Renderer {
|
|
|
329
328
|
return fontFile;
|
|
330
329
|
};
|
|
331
330
|
(0, _svgToPdfkit.default)(this.pdfDocument, svg.svg, svg.x, svg.y, options);
|
|
331
|
+
if (svg.link) {
|
|
332
|
+
this.pdfDocument.link(svg.x, svg.y, svg._width, svg._height, svg.link);
|
|
333
|
+
}
|
|
334
|
+
if (svg.linkToPage) {
|
|
335
|
+
this.pdfDocument.ref({
|
|
336
|
+
Type: 'Action',
|
|
337
|
+
S: 'GoTo',
|
|
338
|
+
D: [svg.linkToPage, 0, 0]
|
|
339
|
+
}).end();
|
|
340
|
+
this.pdfDocument.annotate(svg.x, svg.y, svg._width, svg._height, {
|
|
341
|
+
Subtype: 'Link',
|
|
342
|
+
Dest: [svg.linkToPage - 1, 'XYZ', null, null, null]
|
|
343
|
+
});
|
|
344
|
+
}
|
|
345
|
+
if (svg.linkToDestination) {
|
|
346
|
+
this.pdfDocument.goTo(svg.x, svg.y, svg._width, svg._height, svg.linkToDestination);
|
|
347
|
+
}
|
|
332
348
|
}
|
|
333
349
|
renderAttachment(attachment) {
|
|
334
350
|
const file = this.pdfDocument.provideAttachment(attachment.attachment);
|
|
@@ -363,13 +379,5 @@ class Renderer {
|
|
|
363
379
|
});
|
|
364
380
|
this.pdfDocument.restore();
|
|
365
381
|
}
|
|
366
|
-
_updatePageOrientationInOptions(currentPage) {
|
|
367
|
-
let previousPageOrientation = this.pdfDocument.options.size[0] > this.pdfDocument.options.size[1] ? 'landscape' : 'portrait';
|
|
368
|
-
if (currentPage.pageSize.orientation !== previousPageOrientation) {
|
|
369
|
-
let width = this.pdfDocument.options.size[0];
|
|
370
|
-
let height = this.pdfDocument.options.size[1];
|
|
371
|
-
this.pdfDocument.options.size = [height, width];
|
|
372
|
-
}
|
|
373
|
-
}
|
|
374
382
|
}
|
|
375
383
|
var _default = exports.default = Renderer;
|
package/js/SVGMeasure.js
CHANGED
|
@@ -11,7 +11,7 @@ function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e
|
|
|
11
11
|
* @returns {?number}
|
|
12
12
|
*/
|
|
13
13
|
const stripUnits = textVal => {
|
|
14
|
-
|
|
14
|
+
let n = parseFloat(textVal);
|
|
15
15
|
if (typeof n !== 'number' || isNaN(n)) {
|
|
16
16
|
return undefined;
|
|
17
17
|
}
|
|
@@ -25,7 +25,7 @@ const stripUnits = textVal => {
|
|
|
25
25
|
* @returns {object}
|
|
26
26
|
*/
|
|
27
27
|
const parseSVG = svgString => {
|
|
28
|
-
|
|
28
|
+
let doc;
|
|
29
29
|
try {
|
|
30
30
|
doc = new _xmldoc.default.XmlDocument(svgString);
|
|
31
31
|
} catch (err) {
|
package/js/TextInlines.js
CHANGED
|
@@ -45,7 +45,7 @@ class TextInlines {
|
|
|
45
45
|
* Converts an array of strings (or inline-definition-objects) into a collection
|
|
46
46
|
* of inlines and calculated minWidth/maxWidth and their min/max widths
|
|
47
47
|
*
|
|
48
|
-
* @param {Array} textArray an array of inline-definition-objects (or strings)
|
|
48
|
+
* @param {Array|object} textArray an array of inline-definition-objects (or strings)
|
|
49
49
|
* @param {StyleContextStack} styleContextStack current style stack
|
|
50
50
|
* @returns {object} collection of inlines, minWidth, maxWidth
|
|
51
51
|
*/
|
package/js/URLResolver.js
CHANGED
|
@@ -15,6 +15,7 @@ const fetchUrl = (url, headers = {}) => {
|
|
|
15
15
|
h.get(url, options, res => {
|
|
16
16
|
if (res.statusCode >= 300 && res.statusCode < 400 && res.headers.location) {
|
|
17
17
|
// redirect url
|
|
18
|
+
res.resume();
|
|
18
19
|
fetchUrl(res.headers.location).then(buffer => {
|
|
19
20
|
resolve(buffer);
|
|
20
21
|
}, result => {
|
|
@@ -25,6 +26,8 @@ const fetchUrl = (url, headers = {}) => {
|
|
|
25
26
|
const ok = res.statusCode >= 200 && res.statusCode < 300;
|
|
26
27
|
if (!ok) {
|
|
27
28
|
reject(new TypeError(`Failed to fetch (status code: ${res.statusCode}, url: "${url}")`));
|
|
29
|
+
res.resume();
|
|
30
|
+
return;
|
|
28
31
|
}
|
|
29
32
|
const chunks = [];
|
|
30
33
|
res.on('end', () => resolve(Buffer.concat(chunks)));
|
package/js/helpers/tools.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
|
|
3
3
|
exports.__esModule = true;
|
|
4
|
+
exports.convertToDynamicContent = convertToDynamicContent;
|
|
4
5
|
exports.offsetVector = offsetVector;
|
|
5
6
|
exports.pack = pack;
|
|
6
7
|
function pack(...args) {
|
|
@@ -37,4 +38,9 @@ function offsetVector(vector, x, y) {
|
|
|
37
38
|
}
|
|
38
39
|
break;
|
|
39
40
|
}
|
|
41
|
+
}
|
|
42
|
+
function convertToDynamicContent(staticContent) {
|
|
43
|
+
return () =>
|
|
44
|
+
// copy to new object
|
|
45
|
+
JSON.parse(JSON.stringify(staticContent));
|
|
40
46
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pdfmake",
|
|
3
|
-
"version": "0.3.0-beta.
|
|
3
|
+
"version": "0.3.0-beta.13",
|
|
4
4
|
"description": "Client/server side PDF printing in pure JavaScript",
|
|
5
5
|
"main": "js/index.js",
|
|
6
6
|
"esnext": "src/index.js",
|
|
@@ -10,33 +10,33 @@
|
|
|
10
10
|
},
|
|
11
11
|
"dependencies": {
|
|
12
12
|
"@foliojs-fork/linebreak": "^1.1.2",
|
|
13
|
-
"@foliojs-fork/pdfkit": "^0.
|
|
13
|
+
"@foliojs-fork/pdfkit": "^0.15.2",
|
|
14
14
|
"iconv-lite": "^0.6.3",
|
|
15
15
|
"xmldoc": "^1.3.0"
|
|
16
16
|
},
|
|
17
17
|
"devDependencies": {
|
|
18
|
-
"@babel/cli": "^7.25.
|
|
19
|
-
"@babel/core": "^7.
|
|
20
|
-
"@babel/plugin-transform-modules-commonjs": "^7.
|
|
21
|
-
"@babel/preset-env": "^7.
|
|
22
|
-
"@eslint/js": "^9.
|
|
18
|
+
"@babel/cli": "^7.25.9",
|
|
19
|
+
"@babel/core": "^7.26.0",
|
|
20
|
+
"@babel/plugin-transform-modules-commonjs": "^7.25.9",
|
|
21
|
+
"@babel/preset-env": "^7.26.0",
|
|
22
|
+
"@eslint/js": "^9.14.0",
|
|
23
23
|
"assert": "^2.1.0",
|
|
24
|
-
"babel-loader": "^9.1
|
|
24
|
+
"babel-loader": "^9.2.1",
|
|
25
25
|
"brfs": "^2.0.2",
|
|
26
26
|
"browserify-zlib": "^0.2.0",
|
|
27
27
|
"buffer": "6.0.3",
|
|
28
28
|
"core-js": "3.19.0",
|
|
29
|
-
"eslint": "^9.
|
|
30
|
-
"eslint-plugin-jsdoc": "^50.
|
|
29
|
+
"eslint": "^9.14.0",
|
|
30
|
+
"eslint-plugin-jsdoc": "^50.4.3",
|
|
31
31
|
"expose-loader": "^5.0.0",
|
|
32
32
|
"file-saver": "^2.0.5",
|
|
33
|
-
"globals": "^15.
|
|
34
|
-
"mocha": "^10.
|
|
33
|
+
"globals": "^15.11.0",
|
|
34
|
+
"mocha": "^10.8.2",
|
|
35
35
|
"npm-run-all": "^4.1.5",
|
|
36
36
|
"process": "^0.11.10",
|
|
37
37
|
"rewire": "^7.0.0",
|
|
38
38
|
"shx": "^0.3.4",
|
|
39
|
-
"sinon": "^
|
|
39
|
+
"sinon": "^19.0.2",
|
|
40
40
|
"source-map-loader": "^5.0.0",
|
|
41
41
|
"stream-browserify": "^3.0.0",
|
|
42
42
|
"string-replace-webpack-plugin": "^0.1.3",
|
|
@@ -44,7 +44,7 @@
|
|
|
44
44
|
"terser-webpack-plugin": "^5.3.10",
|
|
45
45
|
"transform-loader": "^0.2.4",
|
|
46
46
|
"util": "^0.12.5",
|
|
47
|
-
"webpack": "^5.
|
|
47
|
+
"webpack": "^5.96.1",
|
|
48
48
|
"webpack-cli": "^5.1.4"
|
|
49
49
|
},
|
|
50
50
|
"engines": {
|
package/src/DocMeasure.js
CHANGED
|
@@ -128,8 +128,16 @@ class DocMeasure {
|
|
|
128
128
|
this.convertIfBase64Image(node);
|
|
129
129
|
|
|
130
130
|
let image = this.pdfDocument.provideImage(node.image);
|
|
131
|
+
|
|
131
132
|
let imageSize = { width: image.width, height: image.height };
|
|
132
133
|
|
|
134
|
+
if (image.constructor.name === 'JPEG') {
|
|
135
|
+
// If EXIF orientation calls for it, swap width and height
|
|
136
|
+
if (image.orientation > 4) {
|
|
137
|
+
imageSize = { width: image.height, height: image.width };
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
|
|
133
141
|
this.measureImageWithDimensions(node, imageSize);
|
|
134
142
|
|
|
135
143
|
return node;
|
package/src/DocumentContext.js
CHANGED
|
@@ -6,30 +6,27 @@ import { EventEmitter } from 'events';
|
|
|
6
6
|
* It facilitates column divisions and vertical sync
|
|
7
7
|
*/
|
|
8
8
|
class DocumentContext extends EventEmitter {
|
|
9
|
-
constructor(
|
|
9
|
+
constructor() {
|
|
10
10
|
super();
|
|
11
11
|
this.pages = [];
|
|
12
|
-
|
|
13
|
-
this.
|
|
14
|
-
|
|
15
|
-
this.
|
|
16
|
-
this.availableWidth = pageSize.width - pageMargins.left - pageMargins.right;
|
|
17
|
-
this.availableHeight = 0;
|
|
12
|
+
this.pageMargins = undefined;
|
|
13
|
+
this.x = undefined;
|
|
14
|
+
this.availableWidth = undefined;
|
|
15
|
+
this.availableHeight = undefined;
|
|
18
16
|
this.page = -1;
|
|
19
17
|
|
|
20
18
|
this.snapshots = [];
|
|
21
19
|
this.backgroundLength = [];
|
|
22
|
-
|
|
23
|
-
this.addPage(pageSize);
|
|
24
20
|
}
|
|
25
21
|
|
|
26
|
-
beginColumnGroup(marginXTopParent) {
|
|
22
|
+
beginColumnGroup(marginXTopParent, bottomByPage = {}) {
|
|
27
23
|
this.snapshots.push({
|
|
28
24
|
x: this.x,
|
|
29
25
|
y: this.y,
|
|
30
26
|
availableHeight: this.availableHeight,
|
|
31
27
|
availableWidth: this.availableWidth,
|
|
32
28
|
page: this.page,
|
|
29
|
+
bottomByPage: bottomByPage ? bottomByPage : {},
|
|
33
30
|
bottomMost: {
|
|
34
31
|
x: this.x,
|
|
35
32
|
y: this.y,
|
|
@@ -46,6 +43,16 @@ class DocumentContext extends EventEmitter {
|
|
|
46
43
|
}
|
|
47
44
|
}
|
|
48
45
|
|
|
46
|
+
updateBottomByPage() {
|
|
47
|
+
const lastSnapshot = this.snapshots[this.snapshots.length - 1];
|
|
48
|
+
const lastPage = this.page;
|
|
49
|
+
let previousBottom = -Number.MIN_VALUE;
|
|
50
|
+
if (lastSnapshot.bottomByPage[lastPage]) {
|
|
51
|
+
previousBottom = lastSnapshot.bottomByPage[lastPage];
|
|
52
|
+
}
|
|
53
|
+
lastSnapshot.bottomByPage[lastPage] = Math.max(previousBottom, this.y);
|
|
54
|
+
}
|
|
55
|
+
|
|
49
56
|
resetMarginXTopParent() {
|
|
50
57
|
this.marginXTopParent = null;
|
|
51
58
|
}
|
|
@@ -118,6 +125,7 @@ class DocumentContext extends EventEmitter {
|
|
|
118
125
|
this.availableHeight -= (y - saved.bottomMost.y);
|
|
119
126
|
}
|
|
120
127
|
this.lastColumnWidth = saved.lastColumnWidth;
|
|
128
|
+
return saved.bottomByPage;
|
|
121
129
|
}
|
|
122
130
|
|
|
123
131
|
addMargin(left, right) {
|
|
@@ -232,8 +240,14 @@ class DocumentContext extends EventEmitter {
|
|
|
232
240
|
};
|
|
233
241
|
}
|
|
234
242
|
|
|
235
|
-
addPage(pageSize) {
|
|
236
|
-
|
|
243
|
+
addPage(pageSize, pageMargin = null) {
|
|
244
|
+
if (pageMargin !== null) {
|
|
245
|
+
this.pageMargins = pageMargin;
|
|
246
|
+
this.x = pageMargin.left;
|
|
247
|
+
this.availableWidth = pageSize.width - pageMargin.left - pageMargin.right;
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
let page = { items: [], pageSize: pageSize, pageMargins: this.pageMargins };
|
|
237
251
|
this.pages.push(page);
|
|
238
252
|
this.backgroundLength.push(0);
|
|
239
253
|
this.page = this.pages.length - 1;
|
package/src/ElementWriter.js
CHANGED
|
@@ -8,12 +8,19 @@ import { EventEmitter } from 'events';
|
|
|
8
8
|
* their positions based on the context
|
|
9
9
|
*/
|
|
10
10
|
class ElementWriter extends EventEmitter {
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* @param {DocumentContext} context
|
|
14
|
+
*/
|
|
11
15
|
constructor(context) {
|
|
12
16
|
super();
|
|
13
17
|
this._context = context;
|
|
14
18
|
this.contextStack = [];
|
|
15
19
|
}
|
|
16
20
|
|
|
21
|
+
/**
|
|
22
|
+
* @returns {DocumentContext}
|
|
23
|
+
*/
|
|
17
24
|
context() {
|
|
18
25
|
return this._context;
|
|
19
26
|
}
|
|
@@ -371,7 +378,7 @@ class ElementWriter extends EventEmitter {
|
|
|
371
378
|
* pushContext(width, height) - creates and pushes a new context with the specified width and height
|
|
372
379
|
* pushContext() - creates a new context for unbreakable blocks (with current availableWidth and full-page-height)
|
|
373
380
|
*
|
|
374
|
-
* @param {
|
|
381
|
+
* @param {DocumentContext|number} contextOrWidth
|
|
375
382
|
* @param {number} height
|
|
376
383
|
*/
|
|
377
384
|
pushContext(contextOrWidth, height) {
|
|
@@ -381,7 +388,9 @@ class ElementWriter extends EventEmitter {
|
|
|
381
388
|
}
|
|
382
389
|
|
|
383
390
|
if (isNumber(contextOrWidth)) {
|
|
384
|
-
|
|
391
|
+
let width = contextOrWidth;
|
|
392
|
+
contextOrWidth = new DocumentContext();
|
|
393
|
+
contextOrWidth.addPage({ width: width, height: height }, { left: 0, right: 0, top: 0, bottom: 0 });
|
|
385
394
|
}
|
|
386
395
|
|
|
387
396
|
this.contextStack.push(this.context());
|