pdfmake 0.3.0-beta.12 → 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.
@@ -172,14 +172,18 @@ class LayoutBuilder {
172
172
  docStructure = this.docPreprocessor.preprocessDocument(docStructure);
173
173
  docStructure = this.docMeasure.measureDocument(docStructure);
174
174
 
175
- this.writer = new PageElementWriter(
176
- new DocumentContext(this.pageSize, this.pageMargins));
175
+ this.writer = new PageElementWriter(new DocumentContext());
177
176
 
178
177
  this.writer.context().addListener('pageAdded', () => {
179
178
  this.addBackground(background);
180
179
  });
181
180
 
182
- this.addBackground(background);
181
+ this.writer.addPage(
182
+ this.pageSize,
183
+ null,
184
+ this.pageMargins
185
+ );
186
+
183
187
  this.processNode(docStructure);
184
188
  this.addHeadersAndFooters(header, footer);
185
189
  if (watermark != null) {
@@ -206,11 +210,6 @@ class LayoutBuilder {
206
210
  }
207
211
  }
208
212
 
209
- addStaticRepeatable(headerOrFooter, sizeFunction) {
210
- this.addDynamicRepeatable(() => // copy to new object
211
- JSON.parse(JSON.stringify(headerOrFooter)), sizeFunction);
212
- }
213
-
214
213
  addDynamicRepeatable(nodeGetter, sizeFunction) {
215
214
  let pages = this.writer.context().pages;
216
215
 
@@ -220,7 +219,7 @@ class LayoutBuilder {
220
219
  let node = nodeGetter(pageIndex + 1, l, this.writer.context().pages[pageIndex].pageSize);
221
220
 
222
221
  if (node) {
223
- let sizes = sizeFunction(this.writer.context().getCurrentPage().pageSize, this.pageMargins);
222
+ let sizes = sizeFunction(this.writer.context().getCurrentPage().pageSize, this.writer.context().getCurrentPage().pageMargins);
224
223
  this.writer.beginUnbreakableBlock(sizes.width, sizes.height);
225
224
  node = this.docPreprocessor.preprocessDocument(node);
226
225
  this.processNode(this.docMeasure.measureDocument(node));
@@ -244,16 +243,12 @@ class LayoutBuilder {
244
243
  height: pageMargins.bottom
245
244
  });
246
245
 
247
- if (typeof header === 'function') {
246
+ if (header) {
248
247
  this.addDynamicRepeatable(header, headerSizeFct);
249
- } else if (header) {
250
- this.addStaticRepeatable(header, headerSizeFct);
251
248
  }
252
249
 
253
- if (typeof footer === 'function') {
250
+ if (footer) {
254
251
  this.addDynamicRepeatable(footer, footerSizeFct);
255
- } else if (footer) {
256
- this.addStaticRepeatable(footer, footerSizeFct);
257
252
  }
258
253
  }
259
254
 
@@ -266,36 +261,40 @@ class LayoutBuilder {
266
261
  return;
267
262
  }
268
263
 
269
- watermark.font = watermark.font || defaultStyle.font || 'Roboto';
270
- watermark.fontSize = watermark.fontSize || 'auto';
271
- watermark.color = watermark.color || 'black';
272
- watermark.opacity = isNumber(watermark.opacity) ? watermark.opacity : 0.6;
273
- watermark.bold = watermark.bold || false;
274
- watermark.italics = watermark.italics || false;
275
- watermark.angle = isValue(watermark.angle) ? watermark.angle : null;
276
-
277
- if (watermark.angle === null) {
278
- watermark.angle = Math.atan2(this.pageSize.height, this.pageSize.width) * -180 / Math.PI;
264
+ let pages = this.writer.context().pages;
265
+ for (let i = 0, l = pages.length; i < l; i++) {
266
+ pages[i].watermark = getWatermarkObject({ ...watermark }, pages[i].pageSize, pdfDocument, defaultStyle);
279
267
  }
280
268
 
281
- if (watermark.fontSize === 'auto') {
282
- watermark.fontSize = getWatermarkFontSize(this.pageSize, watermark, pdfDocument);
283
- }
269
+ function getWatermarkObject(watermark, pageSize, pdfDocument, defaultStyle) {
270
+ watermark.font = watermark.font || defaultStyle.font || 'Roboto';
271
+ watermark.fontSize = watermark.fontSize || 'auto';
272
+ watermark.color = watermark.color || 'black';
273
+ watermark.opacity = isNumber(watermark.opacity) ? watermark.opacity : 0.6;
274
+ watermark.bold = watermark.bold || false;
275
+ watermark.italics = watermark.italics || false;
276
+ watermark.angle = isValue(watermark.angle) ? watermark.angle : null;
277
+
278
+ if (watermark.angle === null) {
279
+ watermark.angle = Math.atan2(pageSize.height, pageSize.width) * -180 / Math.PI;
280
+ }
284
281
 
285
- let watermarkObject = {
286
- text: watermark.text,
287
- font: pdfDocument.provideFont(watermark.font, watermark.bold, watermark.italics),
288
- fontSize: watermark.fontSize,
289
- color: watermark.color,
290
- opacity: watermark.opacity,
291
- angle: watermark.angle
292
- };
282
+ if (watermark.fontSize === 'auto') {
283
+ watermark.fontSize = getWatermarkFontSize(pageSize, watermark, pdfDocument);
284
+ }
293
285
 
294
- watermarkObject._size = getWatermarkSize(watermark, pdfDocument);
286
+ let watermarkObject = {
287
+ text: watermark.text,
288
+ font: pdfDocument.provideFont(watermark.font, watermark.bold, watermark.italics),
289
+ fontSize: watermark.fontSize,
290
+ color: watermark.color,
291
+ opacity: watermark.opacity,
292
+ angle: watermark.angle
293
+ };
295
294
 
296
- let pages = this.writer.context().pages;
297
- for (let i = 0, l = pages.length; i < l; i++) {
298
- pages[i].watermark = watermarkObject;
295
+ watermarkObject._size = getWatermarkSize(watermark, pdfDocument);
296
+
297
+ return watermarkObject;
299
298
  }
300
299
 
301
300
  function getWatermarkSize(watermark, pdfDocument) {
@@ -629,12 +628,12 @@ class LayoutBuilder {
629
628
  * @property {number} target.prevY - Updated to the maximum `prevY` value between `break1` and `break2`.
630
629
  * @property {number} target.y - Updated to the minimum `y` value between `break1` and `break2`.
631
630
  */
632
- _resolveBreakY (break1, break2, target) {
631
+ _resolveBreakY(break1, break2, target) {
633
632
  target.prevY = Math.max(break1.prevY, break2.prevY);
634
633
  target.y = Math.min(break1.y, break2.y);
635
634
  };
636
635
 
637
- _storePageBreakData (data, startsRowSpan, pageBreaks, tableNode) {
636
+ _storePageBreakData(data, startsRowSpan, pageBreaks, tableNode) {
638
637
  if (!startsRowSpan) {
639
638
  let pageDesc = this._getPageBreak(pageBreaks, data.prevPage);
640
639
  let pageDescBySpan = this._getPageBreakListBySpan(tableNode, data.prevPage, data.rowIndex);
@@ -835,7 +834,7 @@ class LayoutBuilder {
835
834
  }
836
835
 
837
836
  return {
838
- pageBreaksBySpan : pageBreaksByRowSpan,
837
+ pageBreaksBySpan: pageBreaksByRowSpan,
839
838
  pageBreaks: pageBreaks,
840
839
  positions: positions
841
840
  };
@@ -1,4 +1,6 @@
1
1
  import ElementWriter from './ElementWriter';
2
+ import { normalizePageSize, normalizePageMargin } from './PageSize';
3
+ import DocumentContext from './DocumentContext';
2
4
 
3
5
  /**
4
6
  * An extended ElementWriter which can handle:
@@ -9,6 +11,10 @@ import ElementWriter from './ElementWriter';
9
11
  * whole block will be rendered on the same page)
10
12
  */
11
13
  class PageElementWriter extends ElementWriter {
14
+
15
+ /**
16
+ * @param {DocumentContext} context
17
+ */
12
18
  constructor(context) {
13
19
  super(context);
14
20
  this.transactionLevel = 0;
@@ -77,6 +83,19 @@ class PageElementWriter extends ElementWriter {
77
83
  });
78
84
  }
79
85
 
86
+ addPage(pageSize, pageOrientation, pageMargin) {
87
+ let prevPage = this.page;
88
+ let prevY = this.y;
89
+
90
+ this.context().addPage(normalizePageSize(pageSize, pageOrientation), normalizePageMargin(pageMargin));
91
+
92
+ this.emit('pageChanged', {
93
+ prevPage: prevPage,
94
+ prevY: prevY,
95
+ y: this.context().y
96
+ });
97
+ }
98
+
80
99
  beginUnbreakableBlock(width, height) {
81
100
  if (this.transactionLevel++ === 0) {
82
101
  this.originalX = this.context().x;
package/src/Printer.js CHANGED
@@ -5,6 +5,7 @@ import { normalizePageSize, normalizePageMargin } from './PageSize';
5
5
  import { tableLayouts } from './tableLayouts';
6
6
  import Renderer from './Renderer';
7
7
  import { isNumber, isValue } from './helpers/variableType';
8
+ import { convertToDynamicContent } from './helpers/tools';
8
9
 
9
10
  /**
10
11
  * Printer which turns document definition into a pdf
@@ -56,6 +57,14 @@ class PdfPrinter {
56
57
  docDefinition.pageMargins = isValue(docDefinition.pageMargins) ? docDefinition.pageMargins : 40;
57
58
  docDefinition.patterns = docDefinition.patterns || {};
58
59
 
60
+ if (docDefinition.header && typeof docDefinition.header !== 'function') {
61
+ docDefinition.header = convertToDynamicContent(docDefinition.header);
62
+ }
63
+
64
+ if (docDefinition.footer && typeof docDefinition.footer !== 'function') {
65
+ docDefinition.footer = convertToDynamicContent(docDefinition.footer);
66
+ }
67
+
59
68
  let pageSize = normalizePageSize(docDefinition.pageSize, docDefinition.pageOrientation);
60
69
 
61
70
  let pdfOptions = {
package/src/Renderer.js CHANGED
@@ -27,7 +27,7 @@ const findFont = (fonts, requiredFonts, defaultFont) => {
27
27
  * @returns {number}
28
28
  */
29
29
  const offsetText = (y, inline) => {
30
- var newY = y;
30
+ let newY = y;
31
31
  if (inline.sup) {
32
32
  newY -= inline.fontSize * 0.75;
33
33
  }
@@ -45,7 +45,6 @@ class Renderer {
45
45
 
46
46
  renderPages(pages) {
47
47
  this.pdfDocument._pdfMakePages = pages; // TODO: Why?
48
- this.pdfDocument.addPage();
49
48
 
50
49
  let totalItems = 0;
51
50
  if (this.progressCallback) {
@@ -57,10 +56,7 @@ class Renderer {
57
56
  let renderedItems = 0;
58
57
 
59
58
  for (let i = 0; i < pages.length; i++) {
60
- if (i > 0) {
61
- this._updatePageOrientationInOptions(pages[i]);
62
- this.pdfDocument.addPage(this.pdfDocument.options);
63
- }
59
+ this.pdfDocument.addPage({ size: [pages[i].pageSize.width, pages[i].pageSize.height] });
64
60
 
65
61
  let page = pages[i];
66
62
  for (let ii = 0, il = page.items.length; ii < il; ii++) {
@@ -353,7 +349,7 @@ class Renderer {
353
349
  this.pdfDocument.link(svg.x, svg.y, svg._width, svg._height, svg.link);
354
350
  }
355
351
  if (svg.linkToPage) {
356
- this.pdfDocument.ref({Type: 'Action', S: 'GoTo', D: [svg.linkToPage, 0, 0]}).end();
352
+ this.pdfDocument.ref({ Type: 'Action', S: 'GoTo', D: [svg.linkToPage, 0, 0] }).end();
357
353
  this.pdfDocument.annotate(svg.x, svg.y, svg._width, svg._height, { Subtype: 'Link', Dest: [svg.linkToPage - 1, 'XYZ', null, null, null] });
358
354
  }
359
355
  if (svg.linkToDestination) {
@@ -402,15 +398,6 @@ class Renderer {
402
398
  this.pdfDocument.restore();
403
399
  }
404
400
 
405
- _updatePageOrientationInOptions(currentPage) {
406
- let previousPageOrientation = this.pdfDocument.options.size[0] > this.pdfDocument.options.size[1] ? 'landscape' : 'portrait';
407
-
408
- if (currentPage.pageSize.orientation !== previousPageOrientation) {
409
- let width = this.pdfDocument.options.size[0];
410
- let height = this.pdfDocument.options.size[1];
411
- this.pdfDocument.options.size = [height, width];
412
- }
413
- }
414
401
  }
415
402
 
416
403
  export default Renderer;
package/src/SVGMeasure.js CHANGED
@@ -7,7 +7,7 @@ import xmldoc from 'xmldoc';
7
7
  * @returns {?number}
8
8
  */
9
9
  const stripUnits = textVal => {
10
- var n = parseFloat(textVal);
10
+ let n = parseFloat(textVal);
11
11
  if (typeof n !== 'number' || isNaN(n)) {
12
12
  return undefined;
13
13
  }
@@ -21,7 +21,7 @@ const stripUnits = textVal => {
21
21
  * @returns {object}
22
22
  */
23
23
  const parseSVG = (svgString) => {
24
- var doc;
24
+ let doc;
25
25
 
26
26
  try {
27
27
  doc = new xmldoc.XmlDocument(svgString);
@@ -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
  */
@@ -11,6 +11,8 @@ const fetchUrl = (url, headers = {}) => {
11
11
 
12
12
  h.get(url, options, res => {
13
13
  if (res.statusCode >= 300 && res.statusCode < 400 && res.headers.location) { // redirect url
14
+ res.resume();
15
+
14
16
  fetchUrl(res.headers.location).then(buffer => {
15
17
  resolve(buffer);
16
18
  }, result => {
@@ -22,6 +24,8 @@ const fetchUrl = (url, headers = {}) => {
22
24
  const ok = res.statusCode >= 200 && res.statusCode < 300;
23
25
  if (!ok) {
24
26
  reject(new TypeError(`Failed to fetch (status code: ${res.statusCode}, url: "${url}")`));
27
+ res.resume();
28
+ return;
25
29
  }
26
30
 
27
31
  const chunks = [];
@@ -37,3 +37,8 @@ export function offsetVector(vector, x, y) {
37
37
  break;
38
38
  }
39
39
  }
40
+
41
+ export function convertToDynamicContent(staticContent) {
42
+ return () => // copy to new object
43
+ JSON.parse(JSON.stringify(staticContent));
44
+ }
@@ -6,4 +6,3 @@ module.exports = {
6
6
  bolditalics: 'Helvetica-BoldOblique'
7
7
  }
8
8
  };
9
-
@@ -1,6 +0,0 @@
1
- <component name="InspectionProjectProfileManager">
2
- <profile version="1.0">
3
- <option name="myName" value="Project Default" />
4
- <inspection_tool class="Eslint" enabled="true" level="WARNING" enabled_by_default="true" />
5
- </profile>
6
- </component>
package/.idea/misc.xml DELETED
@@ -1,6 +0,0 @@
1
- <?xml version="1.0" encoding="UTF-8"?>
2
- <project version="4">
3
- <component name="WebPackConfiguration">
4
- <option name="mode" value="DISABLED" />
5
- </component>
6
- </project>
package/.idea/modules.xml DELETED
@@ -1,8 +0,0 @@
1
- <?xml version="1.0" encoding="UTF-8"?>
2
- <project version="4">
3
- <component name="ProjectModuleManager">
4
- <modules>
5
- <module fileurl="file://$PROJECT_DIR$/.idea/pdfmake.iml" filepath="$PROJECT_DIR$/.idea/pdfmake.iml" />
6
- </modules>
7
- </component>
8
- </project>
package/.idea/pdfmake.iml DELETED
@@ -1,11 +0,0 @@
1
- <?xml version="1.0" encoding="UTF-8"?>
2
- <module type="WEB_MODULE" version="4">
3
- <component name="NewModuleRootManager">
4
- <content url="file://$MODULE_DIR$">
5
- <sourceFolder url="file://$MODULE_DIR$/spec" isTestSource="true" />
6
- <sourceFolder url="file://$MODULE_DIR$/tests" isTestSource="true" />
7
- </content>
8
- <orderEntry type="inheritedJdk" />
9
- <orderEntry type="sourceFolder" forTests="false" />
10
- </component>
11
- </module>
package/.idea/vcs.xml DELETED
@@ -1,6 +0,0 @@
1
- <?xml version="1.0" encoding="UTF-8"?>
2
- <project version="4">
3
- <component name="VcsDirectoryMappings">
4
- <mapping directory="$PROJECT_DIR$" vcs="Git" />
5
- </component>
6
- </project>
package/eslint.config.mjs DELETED
@@ -1,52 +0,0 @@
1
- import jsdoc from "eslint-plugin-jsdoc";
2
- import globals from "globals";
3
- import js from "@eslint/js";
4
-
5
- export default [
6
- {
7
- ignores: ["src/3rd-party/svg-to-pdfkit/*"],
8
- },
9
-
10
- js.configs.recommended,
11
-
12
- {
13
- plugins: {
14
- jsdoc,
15
- },
16
-
17
- languageOptions: {
18
- globals: {
19
- ...globals.browser,
20
- ...globals.node,
21
- ...globals.mocha,
22
- },
23
-
24
- ecmaVersion: 9,
25
- sourceType: "module",
26
- },
27
-
28
- rules: {
29
- semi: 2,
30
- "no-throw-literal": 2,
31
- "no-prototype-builtins": 0,
32
- "jsdoc/check-examples": 0,
33
- "jsdoc/check-param-names": 1,
34
- "jsdoc/check-tag-names": 1,
35
- "jsdoc/check-types": 1,
36
- "jsdoc/no-undefined-types": 1,
37
- "jsdoc/require-description": 0,
38
- "jsdoc/require-description-complete-sentence": 0,
39
- "jsdoc/require-example": 0,
40
- "jsdoc/require-hyphen-before-param-description": 0,
41
- "jsdoc/require-param": 1,
42
- "jsdoc/require-param-description": 0,
43
- "jsdoc/require-param-name": 1,
44
- "jsdoc/require-param-type": 1,
45
- "jsdoc/require-returns": 1,
46
- "jsdoc/require-returns-check": 1,
47
- "jsdoc/require-returns-description": 0,
48
- "jsdoc/require-returns-type": 1,
49
- "jsdoc/valid-types": 1,
50
- },
51
- }
52
- ];