pdfmake 0.3.0-beta.9 → 0.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.
Files changed (74) hide show
  1. package/CHANGELOG.md +7 -48
  2. package/LICENSE +1 -1
  3. package/README.md +78 -85
  4. package/build/pdfmake.js +66833 -75014
  5. package/build/pdfmake.js.map +1 -1
  6. package/build/pdfmake.min.js +2 -2
  7. package/build/pdfmake.min.js.map +1 -1
  8. package/build/vfs_fonts.js +4 -4
  9. package/fonts/Roboto/Roboto-Italic.ttf +0 -0
  10. package/fonts/Roboto/Roboto-Medium.ttf +0 -0
  11. package/fonts/Roboto/Roboto-MediumItalic.ttf +0 -0
  12. package/fonts/Roboto/Roboto-Regular.ttf +0 -0
  13. package/js/DocMeasure.js +20 -1
  14. package/js/DocPreprocessor.js +21 -6
  15. package/js/DocumentContext.js +64 -17
  16. package/js/ElementWriter.js +31 -8
  17. package/js/LayoutBuilder.js +488 -127
  18. package/js/OutputDocument.js +22 -34
  19. package/js/OutputDocumentServer.js +6 -11
  20. package/js/PDFDocument.js +1 -1
  21. package/js/PageElementWriter.js +17 -2
  22. package/js/Printer.js +133 -133
  23. package/js/Renderer.js +22 -14
  24. package/js/SVGMeasure.js +2 -2
  25. package/js/StyleContextStack.js +4 -0
  26. package/js/TableProcessor.js +40 -14
  27. package/js/TextBreaker.js +31 -4
  28. package/js/TextInlines.js +1 -1
  29. package/js/URLResolver.js +25 -55
  30. package/js/base.js +1 -1
  31. package/js/browser-extensions/OutputDocumentBrowser.js +35 -72
  32. package/js/browser-extensions/index.js +2 -2
  33. package/js/browser-extensions/pdfMake.js +0 -12
  34. package/js/browser-extensions/standard-fonts/Courier.js +4 -4
  35. package/js/browser-extensions/standard-fonts/Helvetica.js +4 -4
  36. package/js/browser-extensions/standard-fonts/Symbol.js +1 -1
  37. package/js/browser-extensions/standard-fonts/Times.js +4 -4
  38. package/js/browser-extensions/standard-fonts/ZapfDingbats.js +1 -1
  39. package/js/helpers/tools.js +6 -0
  40. package/js/index.js +1 -1
  41. package/package.json +25 -24
  42. package/src/DocMeasure.js +21 -1
  43. package/src/DocPreprocessor.js +25 -6
  44. package/src/DocumentContext.js +56 -20
  45. package/src/ElementWriter.js +30 -7
  46. package/src/LayoutBuilder.js +531 -144
  47. package/src/OutputDocument.js +23 -37
  48. package/src/OutputDocumentServer.js +6 -11
  49. package/src/PDFDocument.js +1 -1
  50. package/src/PageElementWriter.js +21 -2
  51. package/src/Printer.js +134 -131
  52. package/src/Renderer.js +13 -15
  53. package/src/SVGMeasure.js +2 -2
  54. package/src/StyleContextStack.js +4 -0
  55. package/src/TableProcessor.js +42 -18
  56. package/src/TextBreaker.js +24 -5
  57. package/src/TextInlines.js +1 -1
  58. package/src/URLResolver.js +24 -58
  59. package/src/base.js +1 -1
  60. package/src/browser-extensions/OutputDocumentBrowser.js +33 -71
  61. package/src/browser-extensions/index.js +3 -3
  62. package/src/browser-extensions/pdfMake.js +0 -14
  63. package/src/browser-extensions/standard-fonts/Courier.js +4 -4
  64. package/src/browser-extensions/standard-fonts/Helvetica.js +4 -4
  65. package/src/browser-extensions/standard-fonts/Symbol.js +1 -1
  66. package/src/browser-extensions/standard-fonts/Times.js +4 -4
  67. package/src/browser-extensions/standard-fonts/ZapfDingbats.js +1 -1
  68. package/src/columnCalculator.js +12 -12
  69. package/src/helpers/tools.js +5 -0
  70. package/src/helpers/variableType.js +1 -1
  71. package/src/index.js +1 -1
  72. package/standard-fonts/Helvetica.js +0 -1
  73. package/js/browser-extensions/URLBrowserResolver.js +0 -76
  74. package/src/browser-extensions/URLBrowserResolver.js +0 -84
Binary file
Binary file
Binary file
package/js/DocMeasure.js CHANGED
@@ -31,11 +31,16 @@ class DocMeasure {
31
31
  measureDocument(docStructure) {
32
32
  return this.measureNode(docStructure);
33
33
  }
34
+ measureBlock(node) {
35
+ return this.measureNode(node);
36
+ }
34
37
  measureNode(node) {
35
38
  return this.styleStack.auto(node, () => {
36
39
  // TODO: refactor + rethink whether this is the proper way to handle margins
37
40
  node._margin = (0, _node.getNodeMargin)(node, this.styleStack);
38
- if (node.columns) {
41
+ if (node.section) {
42
+ return extendMargins(this.measureSection(node));
43
+ } else if (node.columns) {
39
44
  return extendMargins(this.measureColumns(node));
40
45
  } else if (node.stack) {
41
46
  return extendMargins(this.measureVerticalContainer(node));
@@ -117,6 +122,14 @@ class DocMeasure {
117
122
  width: image.width,
118
123
  height: image.height
119
124
  };
125
+
126
+ // If EXIF orientation calls for it, swap width and height
127
+ if (image.orientation > 4) {
128
+ imageSize = {
129
+ width: image.height,
130
+ height: image.width
131
+ };
132
+ }
120
133
  this.measureImageWithDimensions(node, imageSize);
121
134
  return node;
122
135
  }
@@ -415,6 +428,12 @@ class DocMeasure {
415
428
  }
416
429
  return node;
417
430
  }
431
+ measureSection(node) {
432
+ // TODO: properties
433
+
434
+ node.section = this.measureNode(node.section);
435
+ return node;
436
+ }
418
437
  measureColumns(node) {
419
438
  let columns = node.columns;
420
439
  node._gap = this.styleStack.getProperty('columnGap') || 0;
@@ -22,9 +22,15 @@ class DocPreprocessor {
22
22
  this.parentNode = null;
23
23
  this.tocs = [];
24
24
  this.nodeReferences = [];
25
- return this.preprocessNode(docStructure);
25
+ return this.preprocessNode(docStructure, true);
26
26
  }
27
- preprocessNode(node) {
27
+ preprocessBlock(node) {
28
+ this.parentNode = null;
29
+ this.tocs = [];
30
+ this.nodeReferences = [];
31
+ return this.preprocessNode(node);
32
+ }
33
+ preprocessNode(node, isSectionAllowed = false) {
28
34
  // expand shortcuts and casting values
29
35
  if (Array.isArray(node)) {
30
36
  node = {
@@ -39,10 +45,15 @@ class DocPreprocessor {
39
45
  // cast value in text property
40
46
  node.text = convertValueToString(node.text);
41
47
  }
42
- if (node.columns) {
48
+ if (node.section) {
49
+ if (!isSectionAllowed) {
50
+ throw new Error(`Incorrect document structure, section node is only allowed at the root level of document structure: ${(0, _node.stringifyNode)(node)}`);
51
+ }
52
+ return this.preprocessSection(node);
53
+ } else if (node.columns) {
43
54
  return this.preprocessColumns(node);
44
55
  } else if (node.stack) {
45
- return this.preprocessVerticalContainer(node);
56
+ return this.preprocessVerticalContainer(node, isSectionAllowed);
46
57
  } else if (node.ul) {
47
58
  return this.preprocessList(node);
48
59
  } else if (node.ol) {
@@ -69,6 +80,10 @@ class DocPreprocessor {
69
80
  throw new Error(`Unrecognized document structure: ${(0, _node.stringifyNode)(node)}`);
70
81
  }
71
82
  }
83
+ preprocessSection(node) {
84
+ node.section = this.preprocessNode(node.section);
85
+ return node;
86
+ }
72
87
  preprocessColumns(node) {
73
88
  let columns = node.columns;
74
89
  for (let i = 0, l = columns.length; i < l; i++) {
@@ -76,10 +91,10 @@ class DocPreprocessor {
76
91
  }
77
92
  return node;
78
93
  }
79
- preprocessVerticalContainer(node) {
94
+ preprocessVerticalContainer(node, isSectionAllowed) {
80
95
  let items = node.stack;
81
96
  for (let i = 0, l = items.length; i < l; i++) {
82
- items[i] = this.preprocessNode(items[i]);
97
+ items[i] = this.preprocessNode(items[i], isSectionAllowed);
83
98
  }
84
99
  return node;
85
100
  }
@@ -9,25 +9,25 @@ var _events = require("events");
9
9
  * It facilitates column divisions and vertical sync
10
10
  */
11
11
  class DocumentContext extends _events.EventEmitter {
12
- constructor(pageSize, pageMargins) {
12
+ constructor() {
13
13
  super();
14
14
  this.pages = [];
15
- this.pageMargins = pageMargins;
16
- this.x = pageMargins.left;
17
- this.availableWidth = pageSize.width - pageMargins.left - pageMargins.right;
18
- this.availableHeight = 0;
15
+ this.pageMargins = undefined;
16
+ this.x = undefined;
17
+ this.availableWidth = undefined;
18
+ this.availableHeight = undefined;
19
19
  this.page = -1;
20
20
  this.snapshots = [];
21
21
  this.backgroundLength = [];
22
- this.addPage(pageSize);
23
22
  }
24
- beginColumnGroup() {
23
+ beginColumnGroup(marginXTopParent, bottomByPage = {}) {
25
24
  this.snapshots.push({
26
25
  x: this.x,
27
26
  y: this.y,
28
27
  availableHeight: this.availableHeight,
29
28
  availableWidth: this.availableWidth,
30
29
  page: this.page,
30
+ bottomByPage: bottomByPage ? bottomByPage : {},
31
31
  bottomMost: {
32
32
  x: this.x,
33
33
  y: this.y,
@@ -38,6 +38,21 @@ class DocumentContext extends _events.EventEmitter {
38
38
  lastColumnWidth: this.lastColumnWidth
39
39
  });
40
40
  this.lastColumnWidth = 0;
41
+ if (marginXTopParent) {
42
+ this.marginXTopParent = marginXTopParent;
43
+ }
44
+ }
45
+ updateBottomByPage() {
46
+ const lastSnapshot = this.snapshots[this.snapshots.length - 1];
47
+ const lastPage = this.page;
48
+ let previousBottom = -Number.MIN_VALUE;
49
+ if (lastSnapshot.bottomByPage[lastPage]) {
50
+ previousBottom = lastSnapshot.bottomByPage[lastPage];
51
+ }
52
+ lastSnapshot.bottomByPage[lastPage] = Math.max(previousBottom, this.y);
53
+ }
54
+ resetMarginXTopParent() {
55
+ this.marginXTopParent = null;
41
56
  }
42
57
  beginColumn(width, offset, endingCell) {
43
58
  let saved = this.snapshots[this.snapshots.length - 1];
@@ -56,10 +71,10 @@ class DocumentContext extends _events.EventEmitter {
56
71
  destContext.bottomMost = bottomMostContext(this, destContext.bottomMost);
57
72
  }
58
73
  }
59
- markEnding(endingCell) {
74
+ markEnding(endingCell, originalXOffset, discountY) {
60
75
  this.page = endingCell._columnEndingContext.page;
61
- this.x = endingCell._columnEndingContext.x;
62
- this.y = endingCell._columnEndingContext.y;
76
+ this.x = endingCell._columnEndingContext.x + originalXOffset;
77
+ this.y = endingCell._columnEndingContext.y - discountY;
63
78
  this.availableWidth = endingCell._columnEndingContext.availableWidth;
64
79
  this.availableHeight = endingCell._columnEndingContext.availableHeight;
65
80
  this.lastColumnWidth = endingCell._columnEndingContext.lastColumnWidth;
@@ -96,6 +111,7 @@ class DocumentContext extends _events.EventEmitter {
96
111
  this.availableHeight -= y - saved.bottomMost.y;
97
112
  }
98
113
  this.lastColumnWidth = saved.lastColumnWidth;
114
+ return saved.bottomByPage;
99
115
  }
100
116
  addMargin(left, right) {
101
117
  this.x += left;
@@ -109,13 +125,27 @@ class DocumentContext extends _events.EventEmitter {
109
125
  initializePage() {
110
126
  this.y = this.pageMargins.top;
111
127
  this.availableHeight = this.getCurrentPage().pageSize.height - this.pageMargins.top - this.pageMargins.bottom;
112
- this.pageSnapshot().availableWidth = this.getCurrentPage().pageSize.width - this.pageMargins.left - this.pageMargins.right;
128
+ const {
129
+ pageCtx,
130
+ isSnapshot
131
+ } = this.pageSnapshot();
132
+ pageCtx.availableWidth = this.getCurrentPage().pageSize.width - this.pageMargins.left - this.pageMargins.right;
133
+ if (isSnapshot && this.marginXTopParent) {
134
+ pageCtx.availableWidth -= this.marginXTopParent[0];
135
+ pageCtx.availableWidth -= this.marginXTopParent[1];
136
+ }
113
137
  }
114
138
  pageSnapshot() {
115
139
  if (this.snapshots[0]) {
116
- return this.snapshots[0];
140
+ return {
141
+ pageCtx: this.snapshots[0],
142
+ isSnapshot: true
143
+ };
117
144
  } else {
118
- return this;
145
+ return {
146
+ pageCtx: this,
147
+ isSnapshot: false
148
+ };
119
149
  }
120
150
  }
121
151
  moveTo(x, y) {
@@ -159,12 +189,22 @@ class DocumentContext extends _events.EventEmitter {
159
189
  let nextPageIndex = this.page + 1;
160
190
  let prevPage = this.page;
161
191
  let prevY = this.y;
192
+
193
+ // If we are in a column group
194
+ if (this.snapshots.length > 0) {
195
+ let lastSnapshot = this.snapshots[this.snapshots.length - 1];
196
+ // We have to update prevY accordingly by also taking into consideration
197
+ // the 'y' of cells that don't break page
198
+ if (lastSnapshot.bottomMost && lastSnapshot.bottomMost.y) {
199
+ prevY = Math.max(this.y, lastSnapshot.bottomMost.y);
200
+ }
201
+ }
162
202
  let createNewPage = nextPageIndex >= this.pages.length;
163
203
  if (createNewPage) {
164
204
  let currentAvailableWidth = this.availableWidth;
165
205
  let currentPageOrientation = this.getCurrentPage().pageSize.orientation;
166
206
  let pageSize = getPageSize(this.getCurrentPage(), pageOrientation);
167
- this.addPage(pageSize);
207
+ this.addPage(pageSize, null, this.getCurrentPage().customProperties);
168
208
  if (currentPageOrientation === pageSize.orientation) {
169
209
  this.availableWidth = currentAvailableWidth;
170
210
  }
@@ -179,16 +219,23 @@ class DocumentContext extends _events.EventEmitter {
179
219
  y: this.y
180
220
  };
181
221
  }
182
- addPage(pageSize) {
222
+ addPage(pageSize, pageMargin = null, customProperties = {}) {
223
+ if (pageMargin !== null) {
224
+ this.pageMargins = pageMargin;
225
+ this.x = pageMargin.left;
226
+ this.availableWidth = pageSize.width - pageMargin.left - pageMargin.right;
227
+ }
183
228
  let page = {
184
229
  items: [],
185
- pageSize: pageSize
230
+ pageSize: pageSize,
231
+ pageMargins: this.pageMargins,
232
+ customProperties: customProperties
186
233
  };
187
234
  this.pages.push(page);
188
235
  this.backgroundLength.push(0);
189
236
  this.page = this.pages.length - 1;
190
237
  this.initializePage();
191
- this.emit('pageAdded');
238
+ this.emit('pageAdded', page);
192
239
  return page;
193
240
  }
194
241
  getCurrentPage() {
@@ -12,11 +12,18 @@ function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e
12
12
  * their positions based on the context
13
13
  */
14
14
  class ElementWriter extends _events.EventEmitter {
15
+ /**
16
+ * @param {DocumentContext} context
17
+ */
15
18
  constructor(context) {
16
19
  super();
17
20
  this._context = context;
18
21
  this.contextStack = [];
19
22
  }
23
+
24
+ /**
25
+ * @returns {DocumentContext}
26
+ */
20
27
  context() {
21
28
  return this._context;
22
29
  }
@@ -204,9 +211,12 @@ class ElementWriter extends _events.EventEmitter {
204
211
  });
205
212
  }
206
213
  }
207
- addVector(vector, ignoreContextX, ignoreContextY, index) {
214
+ addVector(vector, ignoreContextX, ignoreContextY, index, forcePage) {
208
215
  let context = this.context();
209
216
  let page = context.getCurrentPage();
217
+ if ((0, _variableType.isNumber)(forcePage)) {
218
+ page = context.pages[forcePage];
219
+ }
210
220
  let position = this.getCurrentPositionOnPage();
211
221
  if (page) {
212
222
  (0, _tools.offsetVector)(vector, ignoreContextX ? 0 : context.x, ignoreContextY ? 0 : context.y);
@@ -262,10 +272,21 @@ class ElementWriter extends _events.EventEmitter {
262
272
  case 'vector':
263
273
  var v = (0, _tools.pack)(item.item);
264
274
  (0, _tools.offsetVector)(v, useBlockXOffset ? block.xOffset || 0 : ctx.x, useBlockYOffset ? block.yOffset || 0 : ctx.y);
265
- page.items.push({
266
- type: 'vector',
267
- item: v
268
- });
275
+ if (v._isFillColorFromUnbreakable) {
276
+ // If the item is a fillColor from an unbreakable block
277
+ // We have to add it at the beginning of the items body array of the page
278
+ delete v._isFillColorFromUnbreakable;
279
+ const endOfBackgroundItemsIndex = ctx.backgroundLength[ctx.page];
280
+ page.items.splice(endOfBackgroundItemsIndex, 0, {
281
+ type: 'vector',
282
+ item: v
283
+ });
284
+ } else {
285
+ page.items.push({
286
+ type: 'vector',
287
+ item: v
288
+ });
289
+ }
269
290
  break;
270
291
  case 'image':
271
292
  case 'svg':
@@ -292,7 +313,7 @@ class ElementWriter extends _events.EventEmitter {
292
313
  * pushContext(width, height) - creates and pushes a new context with the specified width and height
293
314
  * pushContext() - creates a new context for unbreakable blocks (with current availableWidth and full-page-height)
294
315
  *
295
- * @param {object|number} contextOrWidth
316
+ * @param {DocumentContext|number} contextOrWidth
296
317
  * @param {number} height
297
318
  */
298
319
  pushContext(contextOrWidth, height) {
@@ -301,8 +322,10 @@ class ElementWriter extends _events.EventEmitter {
301
322
  contextOrWidth = this.context().availableWidth;
302
323
  }
303
324
  if ((0, _variableType.isNumber)(contextOrWidth)) {
304
- contextOrWidth = new _DocumentContext.default({
305
- width: contextOrWidth,
325
+ let width = contextOrWidth;
326
+ contextOrWidth = new _DocumentContext.default();
327
+ contextOrWidth.addPage({
328
+ width: width,
306
329
  height: height
307
330
  }, {
308
331
  left: 0,