pdfmake 0.3.0-beta.1 → 0.3.0-beta.11

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.
Files changed (77) hide show
  1. package/.idea/workspace.xml +20 -0
  2. package/CHANGELOG.md +65 -1
  3. package/LICENSE +1 -1
  4. package/README.md +3 -1
  5. package/build/pdfmake.js +65069 -73247
  6. package/build/pdfmake.js.map +1 -1
  7. package/build/pdfmake.min.js +2 -2
  8. package/build/pdfmake.min.js.map +1 -1
  9. package/build/vfs_fonts.js +4 -4
  10. package/eslint.config.mjs +52 -0
  11. package/fonts/Roboto/Roboto-Italic.ttf +0 -0
  12. package/fonts/Roboto/Roboto-Medium.ttf +0 -0
  13. package/fonts/Roboto/Roboto-MediumItalic.ttf +0 -0
  14. package/fonts/Roboto/Roboto-Regular.ttf +0 -0
  15. package/js/3rd-party/svg-to-pdfkit/source.js +247 -922
  16. package/js/3rd-party/svg-to-pdfkit.js +2 -6
  17. package/js/DocMeasure.js +24 -148
  18. package/js/DocPreprocessor.js +8 -55
  19. package/js/DocumentContext.js +44 -62
  20. package/js/ElementWriter.js +42 -74
  21. package/js/LayoutBuilder.js +225 -177
  22. package/js/Line.js +7 -27
  23. package/js/OutputDocument.js +6 -16
  24. package/js/OutputDocumentServer.js +2 -9
  25. package/js/PDFDocument.js +24 -43
  26. package/js/PageElementWriter.js +14 -35
  27. package/js/PageSize.js +3 -17
  28. package/js/Printer.js +102 -49
  29. package/js/Renderer.js +37 -95
  30. package/js/SVGMeasure.js +3 -23
  31. package/js/StyleContextStack.js +13 -55
  32. package/js/TableProcessor.js +94 -136
  33. package/js/TextBreaker.js +4 -47
  34. package/js/TextDecorator.js +3 -41
  35. package/js/TextInlines.js +10 -52
  36. package/js/URLResolver.js +18 -24
  37. package/js/base.js +3 -20
  38. package/js/browser-extensions/OutputDocumentBrowser.js +7 -20
  39. package/js/browser-extensions/URLBrowserResolver.js +7 -20
  40. package/js/browser-extensions/fonts/Roboto.js +0 -4
  41. package/js/browser-extensions/index.js +2 -19
  42. package/js/browser-extensions/pdfMake.js +0 -14
  43. package/js/browser-extensions/standard-fonts/Courier.js +0 -4
  44. package/js/browser-extensions/standard-fonts/Helvetica.js +0 -4
  45. package/js/browser-extensions/standard-fonts/Symbol.js +0 -4
  46. package/js/browser-extensions/standard-fonts/Times.js +0 -4
  47. package/js/browser-extensions/standard-fonts/ZapfDingbats.js +0 -4
  48. package/js/columnCalculator.js +30 -24
  49. package/js/helpers/node.js +3 -27
  50. package/js/helpers/tools.js +0 -8
  51. package/js/helpers/variableType.js +15 -8
  52. package/js/index.js +0 -6
  53. package/js/qrEnc.js +133 -222
  54. package/js/standardPageSizes.js +2 -3
  55. package/js/tableLayouts.js +4 -33
  56. package/js/virtual-fs.js +4 -21
  57. package/package.json +25 -22
  58. package/src/DocMeasure.js +19 -6
  59. package/src/DocPreprocessor.js +6 -0
  60. package/src/DocumentContext.js +35 -20
  61. package/src/ElementWriter.js +45 -5
  62. package/src/LayoutBuilder.js +201 -18
  63. package/src/OutputDocument.js +1 -1
  64. package/src/PDFDocument.js +27 -1
  65. package/src/PageElementWriter.js +6 -2
  66. package/src/Printer.js +93 -7
  67. package/src/Renderer.js +35 -0
  68. package/src/StyleContextStack.js +3 -44
  69. package/src/TableProcessor.js +64 -20
  70. package/src/TextDecorator.js +1 -1
  71. package/src/URLResolver.js +16 -8
  72. package/src/browser-extensions/URLBrowserResolver.js +6 -3
  73. package/src/browser-extensions/index.js +1 -1
  74. package/src/browser-extensions/pdfMake.js +0 -14
  75. package/src/columnCalculator.js +24 -3
  76. package/src/helpers/variableType.js +11 -0
  77. package/src/qrEnc.js +5 -3
package/js/Renderer.js CHANGED
@@ -2,30 +2,23 @@
2
2
 
3
3
  exports.__esModule = true;
4
4
  exports.default = void 0;
5
-
6
5
  var _TextDecorator = _interopRequireDefault(require("./TextDecorator"));
7
-
8
6
  var _TextInlines = _interopRequireDefault(require("./TextInlines"));
9
-
10
7
  var _variableType = require("./helpers/variableType");
11
-
12
8
  var _svgToPdfkit = _interopRequireDefault(require("./3rd-party/svg-to-pdfkit"));
13
-
14
- function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
15
-
9
+ function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
16
10
  const findFont = (fonts, requiredFonts, defaultFont) => {
17
11
  for (let i = 0; i < requiredFonts.length; i++) {
18
12
  let requiredFont = requiredFonts[i].toLowerCase();
19
-
20
13
  for (let font in fonts) {
21
14
  if (font.toLowerCase() === requiredFont) {
22
15
  return font;
23
16
  }
24
17
  }
25
18
  }
26
-
27
19
  return defaultFont;
28
20
  };
21
+
29
22
  /**
30
23
  * Shift the "y" height of the text baseline up or down (superscript or subscript,
31
24
  * respectively). The exact shift can / should be changed according to standard
@@ -35,142 +28,113 @@ const findFont = (fonts, requiredFonts, defaultFont) => {
35
28
  * @param {object} inline
36
29
  * @returns {number}
37
30
  */
38
-
39
-
40
31
  const offsetText = (y, inline) => {
41
32
  var newY = y;
42
-
43
33
  if (inline.sup) {
44
34
  newY -= inline.fontSize * 0.75;
45
35
  }
46
-
47
36
  if (inline.sub) {
48
37
  newY += inline.fontSize * 0.35;
49
38
  }
50
-
51
39
  return newY;
52
40
  };
53
-
54
41
  class Renderer {
55
42
  constructor(pdfDocument, progressCallback) {
56
43
  this.pdfDocument = pdfDocument;
57
44
  this.progressCallback = progressCallback;
58
45
  }
59
-
60
46
  renderPages(pages) {
61
47
  this.pdfDocument._pdfMakePages = pages; // TODO: Why?
62
-
63
48
  this.pdfDocument.addPage();
64
49
  let totalItems = 0;
65
-
66
50
  if (this.progressCallback) {
67
51
  pages.forEach(page => {
68
52
  totalItems += page.items.length;
69
53
  });
70
54
  }
71
-
72
55
  let renderedItems = 0;
73
-
74
56
  for (let i = 0; i < pages.length; i++) {
75
57
  if (i > 0) {
76
58
  this._updatePageOrientationInOptions(pages[i]);
77
-
78
59
  this.pdfDocument.addPage(this.pdfDocument.options);
79
60
  }
80
-
81
61
  let page = pages[i];
82
-
83
62
  for (let ii = 0, il = page.items.length; ii < il; ii++) {
84
63
  let item = page.items[ii];
85
-
86
64
  switch (item.type) {
87
65
  case 'vector':
88
66
  this.renderVector(item.item);
89
67
  break;
90
-
91
68
  case 'line':
92
69
  this.renderLine(item.item, item.item.x, item.item.y);
93
70
  break;
94
-
95
71
  case 'image':
96
72
  this.renderImage(item.item);
97
73
  break;
98
-
99
74
  case 'svg':
100
75
  this.renderSVG(item.item);
101
76
  break;
102
-
77
+ case 'attachment':
78
+ this.renderAttachment(item.item);
79
+ break;
103
80
  case 'beginClip':
104
81
  this.beginClip(item.item);
105
82
  break;
106
-
107
83
  case 'endClip':
108
84
  this.endClip();
109
85
  break;
110
86
  }
111
-
112
87
  renderedItems++;
113
-
114
88
  if (this.progressCallback) {
115
89
  this.progressCallback(renderedItems / totalItems);
116
90
  }
117
91
  }
118
-
119
92
  if (page.watermark) {
120
93
  this.renderWatermark(page);
121
94
  }
122
95
  }
123
96
  }
124
-
125
97
  renderLine(line, x, y) {
126
98
  function preparePageNodeRefLine(_pageNodeRef, inline) {
127
99
  let newWidth;
128
100
  let diffWidth;
129
101
  let textInlines = new _TextInlines.default(null);
130
-
131
102
  if (_pageNodeRef.positions === undefined) {
132
103
  throw new Error('Page reference id not found');
133
104
  }
134
-
135
105
  let pageNumber = _pageNodeRef.positions[0].pageNumber.toString();
136
-
137
106
  inline.text = pageNumber;
138
107
  newWidth = textInlines.widthOfText(inline.text, inline);
139
108
  diffWidth = inline.width - newWidth;
140
109
  inline.width = newWidth;
141
-
142
110
  switch (inline.alignment) {
143
111
  case 'right':
144
112
  inline.x += diffWidth;
145
113
  break;
146
-
147
114
  case 'center':
148
115
  inline.x += diffWidth / 2;
149
116
  break;
150
117
  }
151
118
  }
152
-
153
119
  if (line._pageNodeRef) {
154
120
  preparePageNodeRefLine(line._pageNodeRef, line.inlines[0]);
155
121
  }
156
-
157
122
  x = x || 0;
158
123
  y = y || 0;
159
124
  let lineHeight = line.getHeight();
160
125
  let ascenderHeight = line.getAscenderHeight();
161
126
  let descent = lineHeight - ascenderHeight;
162
127
  const textDecorator = new _TextDecorator.default(this.pdfDocument);
163
- textDecorator.drawBackground(line, x, y); //TODO: line.optimizeInlines();
164
- //TOOD: lines without differently styled inlines should be written to pdf as one stream
128
+ textDecorator.drawBackground(line, x, y);
165
129
 
130
+ //TODO: line.optimizeInlines();
131
+ //TOOD: lines without differently styled inlines should be written to pdf as one stream
166
132
  for (let i = 0, l = line.inlines.length; i < l; i++) {
167
133
  let inline = line.inlines[i];
168
134
  let shiftToBaseline = lineHeight - inline.font.ascender / 1000 * inline.fontSize - descent;
169
-
170
135
  if (inline._pageNodeRef) {
171
136
  preparePageNodeRefLine(inline._pageNodeRef, inline);
172
137
  }
173
-
174
138
  let options = {
175
139
  lineBreak: false,
176
140
  textWidth: inline.width,
@@ -178,19 +142,15 @@ class Renderer {
178
142
  wordCount: 1,
179
143
  link: inline.link
180
144
  };
181
-
182
145
  if (inline.linkToDestination) {
183
146
  options.goTo = inline.linkToDestination;
184
147
  }
185
-
186
148
  if (line.id && i === 0) {
187
149
  options.destination = line.id;
188
150
  }
189
-
190
151
  if (inline.fontFeatures) {
191
152
  options.features = inline.fontFeatures;
192
153
  }
193
-
194
154
  let opacity = (0, _variableType.isNumber)(inline.opacity) ? inline.opacity : 1;
195
155
  this.pdfDocument.opacity(opacity);
196
156
  this.pdfDocument.fill(inline.color || 'black');
@@ -198,7 +158,6 @@ class Renderer {
198
158
  this.pdfDocument.fontSize(inline.fontSize);
199
159
  let shiftedY = offsetText(y + shiftToBaseline, inline);
200
160
  this.pdfDocument.text(inline.text, x + inline.x, shiftedY, options);
201
-
202
161
  if (inline.linkToPage) {
203
162
  this.pdfDocument.ref({
204
163
  Type: 'Action',
@@ -210,16 +169,14 @@ class Renderer {
210
169
  Dest: [inline.linkToPage - 1, 'XYZ', null, null, null]
211
170
  });
212
171
  }
213
- } // Decorations won't draw correctly for superscript
214
-
172
+ }
215
173
 
174
+ // Decorations won't draw correctly for superscript
216
175
  textDecorator.drawDecorations(line, x, y);
217
176
  }
218
-
219
177
  renderVector(vector) {
220
178
  //TODO: pdf optimization (there's no need to write all properties everytime)
221
179
  this.pdfDocument.lineWidth(vector.lineWidth || 1);
222
-
223
180
  if (vector.dash) {
224
181
  this.pdfDocument.dash(vector.dash.length, {
225
182
  space: vector.dash.space || vector.dash.length,
@@ -228,86 +185,66 @@ class Renderer {
228
185
  } else {
229
186
  this.pdfDocument.undash();
230
187
  }
231
-
232
188
  this.pdfDocument.lineJoin(vector.lineJoin || 'miter');
233
- this.pdfDocument.lineCap(vector.lineCap || 'butt'); //TODO: clipping
189
+ this.pdfDocument.lineCap(vector.lineCap || 'butt');
234
190
 
235
- let gradient = null;
191
+ //TODO: clipping
236
192
 
193
+ let gradient = null;
237
194
  switch (vector.type) {
238
195
  case 'ellipse':
239
196
  this.pdfDocument.ellipse(vector.x, vector.y, vector.r1, vector.r2);
240
-
241
197
  if (vector.linearGradient) {
242
198
  gradient = this.pdfDocument.linearGradient(vector.x - vector.r1, vector.y, vector.x + vector.r1, vector.y);
243
199
  }
244
-
245
200
  break;
246
-
247
201
  case 'rect':
248
202
  if (vector.r) {
249
203
  this.pdfDocument.roundedRect(vector.x, vector.y, vector.w, vector.h, vector.r);
250
204
  } else {
251
205
  this.pdfDocument.rect(vector.x, vector.y, vector.w, vector.h);
252
206
  }
253
-
254
207
  if (vector.linearGradient) {
255
208
  gradient = this.pdfDocument.linearGradient(vector.x, vector.y, vector.x + vector.w, vector.y);
256
209
  }
257
-
258
210
  break;
259
-
260
211
  case 'line':
261
212
  this.pdfDocument.moveTo(vector.x1, vector.y1);
262
213
  this.pdfDocument.lineTo(vector.x2, vector.y2);
263
214
  break;
264
-
265
215
  case 'polyline':
266
216
  if (vector.points.length === 0) {
267
217
  break;
268
218
  }
269
-
270
219
  this.pdfDocument.moveTo(vector.points[0].x, vector.points[0].y);
271
-
272
220
  for (let i = 1, l = vector.points.length; i < l; i++) {
273
221
  this.pdfDocument.lineTo(vector.points[i].x, vector.points[i].y);
274
222
  }
275
-
276
223
  if (vector.points.length > 1) {
277
224
  let p1 = vector.points[0];
278
225
  let pn = vector.points[vector.points.length - 1];
279
-
280
226
  if (vector.closePath || p1.x === pn.x && p1.y === pn.y) {
281
227
  this.pdfDocument.closePath();
282
228
  }
283
229
  }
284
-
285
230
  break;
286
-
287
231
  case 'path':
288
232
  this.pdfDocument.path(vector.d);
289
233
  break;
290
234
  }
291
-
292
235
  if (vector.linearGradient && gradient) {
293
236
  let step = 1 / (vector.linearGradient.length - 1);
294
-
295
237
  for (let i = 0; i < vector.linearGradient.length; i++) {
296
238
  gradient.stop(i * step, vector.linearGradient[i]);
297
239
  }
298
-
299
240
  vector.color = gradient;
300
241
  }
301
-
302
242
  let patternColor = this.pdfDocument.providePattern(vector.color);
303
-
304
243
  if (patternColor !== null) {
305
244
  vector.color = patternColor;
306
245
  }
307
-
308
246
  let fillOpacity = (0, _variableType.isNumber)(vector.fillOpacity) ? vector.fillOpacity : 1;
309
247
  let strokeOpacity = (0, _variableType.isNumber)(vector.strokeOpacity) ? vector.strokeOpacity : 1;
310
-
311
248
  if (vector.color && vector.lineColor) {
312
249
  this.pdfDocument.fillColor(vector.color, fillOpacity);
313
250
  this.pdfDocument.strokeColor(vector.lineColor, strokeOpacity);
@@ -320,11 +257,9 @@ class Renderer {
320
257
  this.pdfDocument.stroke();
321
258
  }
322
259
  }
323
-
324
260
  renderImage(image) {
325
261
  let opacity = (0, _variableType.isNumber)(image.opacity) ? image.opacity : 1;
326
262
  this.pdfDocument.opacity(opacity);
327
-
328
263
  if (image.cover) {
329
264
  const align = image.cover.align || 'center';
330
265
  const valign = image.cover.valign || 'center';
@@ -344,11 +279,9 @@ class Renderer {
344
279
  height: image._height
345
280
  });
346
281
  }
347
-
348
282
  if (image.link) {
349
283
  this.pdfDocument.link(image.x, image.y, image._width, image._height, image.link);
350
284
  }
351
-
352
285
  if (image.linkToPage) {
353
286
  this.pdfDocument.ref({
354
287
  Type: 'Action',
@@ -360,45 +293,59 @@ class Renderer {
360
293
  Dest: [image.linkToPage - 1, 'XYZ', null, null, null]
361
294
  });
362
295
  }
363
-
364
296
  if (image.linkToDestination) {
365
297
  this.pdfDocument.goTo(image.x, image.y, image._width, image._height, image.linkToDestination);
366
298
  }
299
+ if (image.linkToFile) {
300
+ const attachment = this.pdfDocument.provideAttachment(image.linkToFile);
301
+ this.pdfDocument.fileAnnotation(image.x, image.y, image._width, image._height, attachment,
302
+ // add empty rectangle as file annotation appearance with the same size as the rendered image
303
+ {
304
+ AP: {
305
+ N: {
306
+ Type: 'XObject',
307
+ Subtype: 'Form',
308
+ FormType: 1,
309
+ BBox: [image.x, image.y, image._width, image._height]
310
+ }
311
+ }
312
+ });
313
+ }
367
314
  }
368
-
369
315
  renderSVG(svg) {
370
316
  let options = Object.assign({
371
317
  width: svg._width,
372
318
  height: svg._height,
373
319
  assumePt: true
374
320
  }, svg.options);
375
-
376
321
  options.fontCallback = (family, bold, italic) => {
377
322
  let fontsFamily = family.split(',').map(f => f.trim().replace(/('|")/g, ''));
378
323
  let font = findFont(this.pdfDocument.fonts, fontsFamily, svg.font || 'Roboto');
379
324
  let fontFile = this.pdfDocument.getFontFile(font, bold, italic);
380
-
381
325
  if (fontFile === null) {
382
326
  let type = this.pdfDocument.getFontType(bold, italic);
383
327
  throw new Error(`Font '${font}' in style '${type}' is not defined in the font section of the document definition.`);
384
328
  }
385
-
386
329
  return fontFile;
387
330
  };
388
-
389
331
  (0, _svgToPdfkit.default)(this.pdfDocument, svg.svg, svg.x, svg.y, options);
390
332
  }
391
-
333
+ renderAttachment(attachment) {
334
+ const file = this.pdfDocument.provideAttachment(attachment.attachment);
335
+ const options = {};
336
+ if (attachment.icon) {
337
+ options.Name = attachment.icon;
338
+ }
339
+ this.pdfDocument.fileAnnotation(attachment.x, attachment.y, attachment._width, attachment._height, file, options);
340
+ }
392
341
  beginClip(rect) {
393
342
  this.pdfDocument.save();
394
343
  this.pdfDocument.addContent(`${rect.x} ${rect.y} ${rect.width} ${rect.height} re`);
395
344
  this.pdfDocument.clip();
396
345
  }
397
-
398
346
  endClip() {
399
347
  this.pdfDocument.restore();
400
348
  }
401
-
402
349
  renderWatermark(page) {
403
350
  let watermark = page.watermark;
404
351
  this.pdfDocument.fill(watermark.color);
@@ -416,18 +363,13 @@ class Renderer {
416
363
  });
417
364
  this.pdfDocument.restore();
418
365
  }
419
-
420
366
  _updatePageOrientationInOptions(currentPage) {
421
367
  let previousPageOrientation = this.pdfDocument.options.size[0] > this.pdfDocument.options.size[1] ? 'landscape' : 'portrait';
422
-
423
368
  if (currentPage.pageSize.orientation !== previousPageOrientation) {
424
369
  let width = this.pdfDocument.options.size[0];
425
370
  let height = this.pdfDocument.options.size[1];
426
371
  this.pdfDocument.options.size = [height, width];
427
372
  }
428
373
  }
429
-
430
374
  }
431
-
432
- var _default = Renderer;
433
- exports.default = _default;
375
+ var _default = exports.default = Renderer;
package/js/SVGMeasure.js CHANGED
@@ -2,11 +2,8 @@
2
2
 
3
3
  exports.__esModule = true;
4
4
  exports.default = void 0;
5
-
6
5
  var _xmldoc = _interopRequireDefault(require("xmldoc"));
7
-
8
- function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
9
-
6
+ function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
10
7
  /**
11
8
  * Strip unit postfix, parse number, but return undefined instead of NaN for bad input
12
9
  *
@@ -15,75 +12,58 @@ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { de
15
12
  */
16
13
  const stripUnits = textVal => {
17
14
  var n = parseFloat(textVal);
18
-
19
15
  if (typeof n !== 'number' || isNaN(n)) {
20
16
  return undefined;
21
17
  }
22
-
23
18
  return n;
24
19
  };
20
+
25
21
  /**
26
22
  * Make sure it's valid XML and the root tage is <svg/>, returns xmldoc DOM
27
23
  *
28
24
  * @param {string} svgString
29
25
  * @returns {object}
30
26
  */
31
-
32
-
33
27
  const parseSVG = svgString => {
34
28
  var doc;
35
-
36
29
  try {
37
30
  doc = new _xmldoc.default.XmlDocument(svgString);
38
31
  } catch (err) {
39
32
  throw new Error('SVGMeasure: ' + err);
40
33
  }
41
-
42
34
  if (doc.name !== "svg") {
43
35
  throw new Error('SVGMeasure: expected <svg> document');
44
36
  }
45
-
46
37
  return doc;
47
38
  };
48
-
49
39
  class SVGMeasure {
50
40
  constructor() {}
51
-
52
41
  measureSVG(svgString) {
53
42
  let doc = parseSVG(svgString);
54
43
  let docWidth = stripUnits(doc.attr.width);
55
44
  let docHeight = stripUnits(doc.attr.height);
56
-
57
45
  if ((docWidth === undefined || docHeight === undefined) && typeof doc.attr.viewBox === 'string') {
58
46
  let viewBoxParts = doc.attr.viewBox.split(/[,\s]+/);
59
-
60
47
  if (viewBoxParts.length !== 4) {
61
48
  throw new Error("Unexpected svg viewbox format, should have 4 entries but found: '" + doc.attr.viewBox + "'");
62
49
  }
63
-
64
50
  if (docWidth === undefined) {
65
51
  docWidth = stripUnits(viewBoxParts[2]);
66
52
  }
67
-
68
53
  if (docHeight === undefined) {
69
54
  docHeight = stripUnits(viewBoxParts[3]);
70
55
  }
71
56
  }
72
-
73
57
  return {
74
58
  width: docWidth,
75
59
  height: docHeight
76
60
  };
77
61
  }
78
-
79
62
  writeDimensions(svgString, dimensions) {
80
63
  let doc = parseSVG(svgString);
81
64
  doc.attr.width = "" + dimensions.width;
82
65
  doc.attr.height = "" + dimensions.height;
83
66
  return doc.toString();
84
67
  }
85
-
86
68
  }
87
-
88
- var _default = SVGMeasure;
89
- exports.default = _default;
69
+ var _default = exports.default = SVGMeasure;