pdfmake-acroforms 0.3.4-beta.1

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 (119) hide show
  1. package/CHANGELOG.md +60 -0
  2. package/LICENSE +21 -0
  3. package/README.md +75 -0
  4. package/build/fonts/Roboto/Roboto-Italic.ttf +0 -0
  5. package/build/fonts/Roboto/Roboto-Medium.ttf +0 -0
  6. package/build/fonts/Roboto/Roboto-MediumItalic.ttf +0 -0
  7. package/build/fonts/Roboto/Roboto-Regular.ttf +0 -0
  8. package/build/fonts/Roboto.js +27 -0
  9. package/build/pdfmake.js +67806 -0
  10. package/build/pdfmake.js.map +1 -0
  11. package/build/pdfmake.min.js +3 -0
  12. package/build/pdfmake.min.js.map +1 -0
  13. package/build/standard-fonts/Courier.js +27 -0
  14. package/build/standard-fonts/Helvetica.js +27 -0
  15. package/build/standard-fonts/Symbol.js +21 -0
  16. package/build/standard-fonts/Times.js +27 -0
  17. package/build/standard-fonts/ZapfDingbats.js +21 -0
  18. package/build/vfs_fonts.js +6 -0
  19. package/build-vfs.js +44 -0
  20. package/fonts/Roboto/Roboto-Italic.ttf +0 -0
  21. package/fonts/Roboto/Roboto-Medium.ttf +0 -0
  22. package/fonts/Roboto/Roboto-MediumItalic.ttf +0 -0
  23. package/fonts/Roboto/Roboto-Regular.ttf +0 -0
  24. package/fonts/Roboto.js +8 -0
  25. package/index.d.ts +40 -0
  26. package/interfaces.d.ts +2610 -0
  27. package/js/3rd-party/svg-to-pdfkit/source.js +3823 -0
  28. package/js/3rd-party/svg-to-pdfkit.js +7 -0
  29. package/js/DocMeasure.js +675 -0
  30. package/js/DocPreprocessor.js +258 -0
  31. package/js/DocumentContext.js +310 -0
  32. package/js/ElementWriter.js +399 -0
  33. package/js/LayoutBuilder.js +1202 -0
  34. package/js/Line.js +101 -0
  35. package/js/OutputDocument.js +64 -0
  36. package/js/OutputDocumentServer.js +29 -0
  37. package/js/PDFDocument.js +145 -0
  38. package/js/PageElementWriter.js +164 -0
  39. package/js/PageSize.js +74 -0
  40. package/js/Printer.js +288 -0
  41. package/js/Renderer.js +513 -0
  42. package/js/SVGMeasure.js +92 -0
  43. package/js/StyleContextStack.js +191 -0
  44. package/js/TableProcessor.js +562 -0
  45. package/js/TextBreaker.js +179 -0
  46. package/js/TextDecorator.js +152 -0
  47. package/js/TextInlines.js +212 -0
  48. package/js/URLResolver.js +43 -0
  49. package/js/base.js +59 -0
  50. package/js/browser-extensions/OutputDocumentBrowser.js +82 -0
  51. package/js/browser-extensions/fonts/Roboto.js +38 -0
  52. package/js/browser-extensions/index.js +53 -0
  53. package/js/browser-extensions/pdfMake.js +3 -0
  54. package/js/browser-extensions/standard-fonts/Courier.js +38 -0
  55. package/js/browser-extensions/standard-fonts/Helvetica.js +38 -0
  56. package/js/browser-extensions/standard-fonts/Symbol.js +23 -0
  57. package/js/browser-extensions/standard-fonts/Times.js +38 -0
  58. package/js/browser-extensions/standard-fonts/ZapfDingbats.js +23 -0
  59. package/js/browser-extensions/virtual-fs-cjs.js +3 -0
  60. package/js/columnCalculator.js +148 -0
  61. package/js/helpers/node.js +122 -0
  62. package/js/helpers/tools.js +46 -0
  63. package/js/helpers/variableType.js +59 -0
  64. package/js/index.d.ts +40 -0
  65. package/js/index.js +15 -0
  66. package/js/interfaces.d.ts +2610 -0
  67. package/js/qrEnc.js +721 -0
  68. package/js/standardPageSizes.js +56 -0
  69. package/js/tableLayouts.js +98 -0
  70. package/js/virtual-fs.js +60 -0
  71. package/package.json +95 -0
  72. package/src/3rd-party/svg-to-pdfkit/LICENSE +9 -0
  73. package/src/3rd-party/svg-to-pdfkit/source.js +2745 -0
  74. package/src/3rd-party/svg-to-pdfkit.js +3 -0
  75. package/src/DocMeasure.js +768 -0
  76. package/src/DocPreprocessor.js +289 -0
  77. package/src/DocumentContext.js +345 -0
  78. package/src/ElementWriter.js +468 -0
  79. package/src/LayoutBuilder.js +1366 -0
  80. package/src/Line.js +108 -0
  81. package/src/OutputDocument.js +64 -0
  82. package/src/OutputDocumentServer.js +32 -0
  83. package/src/PDFDocument.js +178 -0
  84. package/src/PageElementWriter.js +191 -0
  85. package/src/PageSize.js +53 -0
  86. package/src/Printer.js +306 -0
  87. package/src/Renderer.js +546 -0
  88. package/src/SVGMeasure.js +109 -0
  89. package/src/StyleContextStack.js +208 -0
  90. package/src/TableProcessor.js +620 -0
  91. package/src/TextBreaker.js +181 -0
  92. package/src/TextDecorator.js +175 -0
  93. package/src/TextInlines.js +229 -0
  94. package/src/URLResolver.js +43 -0
  95. package/src/base.js +70 -0
  96. package/src/browser-extensions/OutputDocumentBrowser.js +80 -0
  97. package/src/browser-extensions/fonts/Roboto.js +27 -0
  98. package/src/browser-extensions/index.js +55 -0
  99. package/src/browser-extensions/pdfMake.js +1 -0
  100. package/src/browser-extensions/standard-fonts/Courier.js +27 -0
  101. package/src/browser-extensions/standard-fonts/Helvetica.js +27 -0
  102. package/src/browser-extensions/standard-fonts/Symbol.js +21 -0
  103. package/src/browser-extensions/standard-fonts/Times.js +27 -0
  104. package/src/browser-extensions/standard-fonts/ZapfDingbats.js +21 -0
  105. package/src/browser-extensions/virtual-fs-cjs.js +1 -0
  106. package/src/columnCalculator.js +154 -0
  107. package/src/helpers/node.js +134 -0
  108. package/src/helpers/tools.js +44 -0
  109. package/src/helpers/variableType.js +50 -0
  110. package/src/index.js +16 -0
  111. package/src/qrEnc.js +796 -0
  112. package/src/standardPageSizes.js +52 -0
  113. package/src/tableLayouts.js +100 -0
  114. package/src/virtual-fs.js +66 -0
  115. package/standard-fonts/Courier.js +8 -0
  116. package/standard-fonts/Helvetica.js +8 -0
  117. package/standard-fonts/Symbol.js +5 -0
  118. package/standard-fonts/Times.js +8 -0
  119. package/standard-fonts/ZapfDingbats.js +5 -0
@@ -0,0 +1,289 @@
1
+ import { isString, isNumber, isValue, isEmptyObject } from './helpers/variableType';
2
+ import { stringifyNode } from './helpers/node';
3
+
4
+ const convertValueToString = value => {
5
+ if (isString(value)) {
6
+ return value.replace(/\t/g, ' '); // expand tab as spaces
7
+ } else if (isNumber(value) || typeof value === 'boolean') {
8
+ return value.toString();
9
+ } else if (!isValue(value) || isEmptyObject(value)) {
10
+ return '';
11
+ }
12
+
13
+ // TODO: throw exception ?
14
+
15
+ return value;
16
+ };
17
+
18
+ class DocPreprocessor {
19
+ preprocessDocument(docStructure) {
20
+ this.parentNode = null;
21
+ this.tocs = [];
22
+ this.nodeReferences = [];
23
+ return this.preprocessNode(docStructure, true);
24
+ }
25
+
26
+ preprocessBlock(node) {
27
+ this.parentNode = null;
28
+ this.tocs = [];
29
+ this.nodeReferences = [];
30
+ return this.preprocessNode(node);
31
+ }
32
+
33
+ preprocessNode(node, isSectionAllowed = false) {
34
+ // expand shortcuts and casting values
35
+ if (Array.isArray(node)) {
36
+ node = { stack: node };
37
+ } else if (isString(node) || isNumber(node) || typeof node === 'boolean' || !isValue(node) || isEmptyObject(node)) { // text node defined as value
38
+ node = { text: convertValueToString(node) };
39
+ } else if ('text' in node) { // cast value in text property
40
+ node.text = convertValueToString(node.text);
41
+ }
42
+
43
+ if (node.section) {
44
+ if (!isSectionAllowed) {
45
+ throw new Error(`Incorrect document structure, section node is only allowed at the root level of document structure: ${stringifyNode(node)}`);
46
+ }
47
+
48
+ return this.preprocessSection(node);
49
+ } else if (node.columns) {
50
+ return this.preprocessColumns(node);
51
+ } else if (node.stack) {
52
+ return this.preprocessVerticalContainer(node, isSectionAllowed);
53
+ } else if (node.ul) {
54
+ return this.preprocessList(node);
55
+ } else if (node.ol) {
56
+ return this.preprocessList(node);
57
+ } else if (node.table) {
58
+ return this.preprocessTable(node);
59
+ } else if (node.text !== undefined) {
60
+ return this.preprocessText(node);
61
+ } else if (node.toc) {
62
+ return this.preprocessToc(node);
63
+ } else if (node.image) {
64
+ return this.preprocessImage(node);
65
+ } else if (node.svg) {
66
+ return this.preprocessSVG(node);
67
+ } else if (node.canvas) {
68
+ return this.preprocessCanvas(node);
69
+ } else if (node.qr) {
70
+ return this.preprocessQr(node);
71
+ } else if (node.attachment) {
72
+ return this.preprocessAttachment(node);
73
+ } else if (node.pageReference || node.textReference) {
74
+ return this.preprocessText(node);
75
+ } else if (node.acroform) {
76
+ return this.preprocessAcroForm(node);
77
+ } else {
78
+ throw new Error(`Unrecognized document structure: ${stringifyNode(node)}`);
79
+ }
80
+ }
81
+
82
+ preprocessAcroForm(node) {
83
+ return node;
84
+ }
85
+
86
+ preprocessSection(node) {
87
+ node.section = this.preprocessNode(node.section);
88
+
89
+ return node;
90
+ }
91
+
92
+ preprocessColumns(node) {
93
+ let columns = node.columns;
94
+
95
+ for (let i = 0, l = columns.length; i < l; i++) {
96
+ columns[i] = this.preprocessNode(columns[i]);
97
+ }
98
+
99
+ return node;
100
+ }
101
+
102
+ preprocessVerticalContainer(node, isSectionAllowed) {
103
+ let items = node.stack;
104
+
105
+ for (let i = 0, l = items.length; i < l; i++) {
106
+ items[i] = this.preprocessNode(items[i], isSectionAllowed);
107
+ }
108
+
109
+ return node;
110
+ }
111
+
112
+ preprocessList(node) {
113
+ let items = node.ul || node.ol;
114
+
115
+ for (let i = 0, l = items.length; i < l; i++) {
116
+ items[i] = this.preprocessNode(items[i]);
117
+ }
118
+
119
+ return node;
120
+ }
121
+
122
+ preprocessTable(node) {
123
+ let col;
124
+ let row;
125
+ let cols;
126
+ let rows;
127
+
128
+ for (col = 0, cols = node.table.body[0].length; col < cols; col++) {
129
+ for (row = 0, rows = node.table.body.length; row < rows; row++) {
130
+ let rowData = node.table.body[row];
131
+ let data = rowData[col];
132
+ if (data !== undefined) {
133
+ if (data === null) { // transform to object
134
+ data = '';
135
+ }
136
+ if (!data._span) {
137
+ rowData[col] = this.preprocessNode(data);
138
+ }
139
+ }
140
+ }
141
+ }
142
+
143
+ return node;
144
+ }
145
+
146
+ preprocessText(node) {
147
+ if (node.tocItem) {
148
+ if (!Array.isArray(node.tocItem)) {
149
+ node.tocItem = [node.tocItem];
150
+ }
151
+
152
+ for (let i = 0, l = node.tocItem.length; i < l; i++) {
153
+ if (!isString(node.tocItem[i])) {
154
+ node.tocItem[i] = '_default_';
155
+ }
156
+
157
+ let tocItemId = node.tocItem[i];
158
+
159
+ if (!this.tocs[tocItemId]) {
160
+ this.tocs[tocItemId] = { toc: { _items: [], _pseudo: true } };
161
+ }
162
+
163
+ if (!node.id) {
164
+ node.id = `toc-${tocItemId}-${this.tocs[tocItemId].toc._items.length}`;
165
+ }
166
+
167
+ let tocItemRef = {
168
+ _nodeRef: this._getNodeForNodeRef(node),
169
+ _textNodeRef: node
170
+ };
171
+ this.tocs[tocItemId].toc._items.push(tocItemRef);
172
+ }
173
+ }
174
+
175
+ if (node.id) {
176
+ if (this.nodeReferences[node.id]) {
177
+ if (!this.nodeReferences[node.id]._pseudo) {
178
+ throw new Error(`Node id '${node.id}' already exists`);
179
+ }
180
+
181
+ this.nodeReferences[node.id]._nodeRef = this._getNodeForNodeRef(node);
182
+ this.nodeReferences[node.id]._textNodeRef = node;
183
+ this.nodeReferences[node.id]._pseudo = false;
184
+ } else {
185
+ this.nodeReferences[node.id] = {
186
+ _nodeRef: this._getNodeForNodeRef(node),
187
+ _textNodeRef: node
188
+ };
189
+ }
190
+ }
191
+
192
+ if (node.pageReference) {
193
+ if (!this.nodeReferences[node.pageReference]) {
194
+ this.nodeReferences[node.pageReference] = {
195
+ _nodeRef: {},
196
+ _textNodeRef: {},
197
+ _pseudo: true
198
+ };
199
+ }
200
+ node.text = '00000';
201
+ node.linkToDestination = node.pageReference;
202
+ node._pageRef = this.nodeReferences[node.pageReference];
203
+ }
204
+
205
+ if (node.textReference) {
206
+ if (!this.nodeReferences[node.textReference]) {
207
+ this.nodeReferences[node.textReference] = { _nodeRef: {}, _pseudo: true };
208
+ }
209
+
210
+ node.text = '';
211
+ node.linkToDestination = node.textReference;
212
+ node._textRef = this.nodeReferences[node.textReference];
213
+ }
214
+
215
+ if (node.text && node.text.text) {
216
+ node.text = [this.preprocessNode(node.text)];
217
+ } else if (Array.isArray(node.text)) {
218
+ let isSetParentNode = false;
219
+ if (this.parentNode === null) {
220
+ this.parentNode = node;
221
+ isSetParentNode = true;
222
+ }
223
+
224
+ for (let i = 0, l = node.text.length; i < l; i++) {
225
+ node.text[i] = this.preprocessNode(node.text[i]);
226
+ }
227
+
228
+ if (isSetParentNode) {
229
+ this.parentNode = null;
230
+ }
231
+ }
232
+
233
+ return node;
234
+ }
235
+
236
+ preprocessToc(node) {
237
+ if (!node.toc.id) {
238
+ node.toc.id = '_default_';
239
+ }
240
+
241
+ node.toc.title = node.toc.title ? this.preprocessNode(node.toc.title) : null;
242
+ node.toc._items = [];
243
+
244
+ if (this.tocs[node.toc.id]) {
245
+ if (!this.tocs[node.toc.id].toc._pseudo) {
246
+ throw new Error(`TOC '${node.toc.id}' already exists`);
247
+ }
248
+
249
+ node.toc._items = this.tocs[node.toc.id].toc._items;
250
+ }
251
+
252
+ this.tocs[node.toc.id] = node;
253
+
254
+ return node;
255
+ }
256
+
257
+ preprocessImage(node) {
258
+ if ((node.image.type !== undefined) && (node.image.data !== undefined) && (node.image.type === 'Buffer') && Array.isArray(node.image.data)) {
259
+ node.image = Buffer.from(node.image.data);
260
+ }
261
+ return node;
262
+ }
263
+
264
+ preprocessCanvas(node) {
265
+ return node;
266
+ }
267
+
268
+ preprocessSVG(node) {
269
+ return node;
270
+ }
271
+
272
+ preprocessQr(node) {
273
+ return node;
274
+ }
275
+
276
+ preprocessAttachment(node) {
277
+ return node;
278
+ }
279
+
280
+ _getNodeForNodeRef(node) {
281
+ if (this.parentNode) {
282
+ return this.parentNode;
283
+ }
284
+
285
+ return node;
286
+ }
287
+ }
288
+
289
+ export default DocPreprocessor;
@@ -0,0 +1,345 @@
1
+ import { isString } from './helpers/variableType';
2
+ import { EventEmitter } from 'events';
3
+
4
+ /**
5
+ * A store for current x, y positions and available width/height.
6
+ * It facilitates column divisions and vertical sync
7
+ */
8
+ class DocumentContext extends EventEmitter {
9
+ constructor() {
10
+ super();
11
+ this.pages = [];
12
+ this.pageMargins = undefined;
13
+ this.x = undefined;
14
+ this.availableWidth = undefined;
15
+ this.availableHeight = undefined;
16
+ this.page = -1;
17
+
18
+ this.snapshots = [];
19
+ this.backgroundLength = [];
20
+ }
21
+
22
+ beginColumnGroup(marginXTopParent, bottomByPage = {}) {
23
+ this.snapshots.push({
24
+ x: this.x,
25
+ y: this.y,
26
+ availableHeight: this.availableHeight,
27
+ availableWidth: this.availableWidth,
28
+ page: this.page,
29
+ bottomByPage: bottomByPage ? bottomByPage : {},
30
+ bottomMost: {
31
+ x: this.x,
32
+ y: this.y,
33
+ availableHeight: this.availableHeight,
34
+ availableWidth: this.availableWidth,
35
+ page: this.page
36
+ },
37
+ lastColumnWidth: this.lastColumnWidth
38
+ });
39
+
40
+ this.lastColumnWidth = 0;
41
+ if (marginXTopParent) {
42
+ this.marginXTopParent = marginXTopParent;
43
+ }
44
+ }
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
+
56
+ resetMarginXTopParent() {
57
+ this.marginXTopParent = null;
58
+ }
59
+
60
+ beginColumn(width, offset, endingCell) {
61
+ let saved = this.snapshots[this.snapshots.length - 1];
62
+
63
+ this.calculateBottomMost(saved, endingCell);
64
+
65
+ this.page = saved.page;
66
+ this.x = this.x + this.lastColumnWidth + (offset || 0);
67
+ this.y = saved.y;
68
+ this.availableWidth = width; //saved.availableWidth - offset;
69
+ this.availableHeight = saved.availableHeight;
70
+
71
+ this.lastColumnWidth = width;
72
+ }
73
+
74
+ calculateBottomMost(destContext, endingCell) {
75
+ if (endingCell) {
76
+ this.saveContextInEndingCell(endingCell);
77
+ } else {
78
+ destContext.bottomMost = bottomMostContext(this, destContext.bottomMost);
79
+ }
80
+ }
81
+
82
+ markEnding(endingCell, originalXOffset, discountY) {
83
+ this.page = endingCell._columnEndingContext.page;
84
+ this.x = endingCell._columnEndingContext.x + originalXOffset;
85
+ this.y = endingCell._columnEndingContext.y - discountY;
86
+ this.availableWidth = endingCell._columnEndingContext.availableWidth;
87
+ this.availableHeight = endingCell._columnEndingContext.availableHeight;
88
+ this.lastColumnWidth = endingCell._columnEndingContext.lastColumnWidth;
89
+ }
90
+
91
+ saveContextInEndingCell(endingCell) {
92
+ endingCell._columnEndingContext = {
93
+ page: this.page,
94
+ x: this.x,
95
+ y: this.y,
96
+ availableHeight: this.availableHeight,
97
+ availableWidth: this.availableWidth,
98
+ lastColumnWidth: this.lastColumnWidth
99
+ };
100
+ }
101
+
102
+ completeColumnGroup(height, endingCell) {
103
+ let saved = this.snapshots.pop();
104
+
105
+ this.calculateBottomMost(saved, endingCell);
106
+
107
+ this.x = saved.x;
108
+
109
+ let y = saved.bottomMost.y;
110
+ if (height) {
111
+ if (saved.page === saved.bottomMost.page) {
112
+ if ((saved.y + height) > y) {
113
+ y = saved.y + height;
114
+ }
115
+ } else {
116
+ y += height;
117
+ }
118
+ }
119
+
120
+ this.y = y;
121
+ this.page = saved.bottomMost.page;
122
+ this.availableWidth = saved.availableWidth;
123
+ this.availableHeight = saved.bottomMost.availableHeight;
124
+ if (height) {
125
+ this.availableHeight -= (y - saved.bottomMost.y);
126
+ }
127
+
128
+ if (height && (saved.bottomMost.y - saved.y < height)) {
129
+ this.height = height;
130
+ } else {
131
+ this.height = saved.bottomMost.y - saved.y;
132
+ }
133
+
134
+ this.lastColumnWidth = saved.lastColumnWidth;
135
+ return saved.bottomByPage;
136
+ }
137
+
138
+ addMargin(left, right) {
139
+ this.x += left;
140
+ this.availableWidth -= left + (right || 0);
141
+ }
142
+
143
+ moveDown(offset) {
144
+ this.y += offset;
145
+ this.availableHeight -= offset;
146
+
147
+ return this.availableHeight > 0;
148
+ }
149
+
150
+ initializePage() {
151
+ this.y = this.pageMargins.top;
152
+ this.availableHeight = this.getCurrentPage().pageSize.height - this.pageMargins.top - this.pageMargins.bottom;
153
+ const { pageCtx, isSnapshot } = this.pageSnapshot();
154
+ pageCtx.availableWidth = this.getCurrentPage().pageSize.width - this.pageMargins.left - this.pageMargins.right;
155
+ if (isSnapshot && this.marginXTopParent) {
156
+ pageCtx.availableWidth -= this.marginXTopParent[0];
157
+ pageCtx.availableWidth -= this.marginXTopParent[1];
158
+ }
159
+ }
160
+
161
+ pageSnapshot() {
162
+ if (this.snapshots[0]) {
163
+ return { pageCtx: this.snapshots[0], isSnapshot: true };
164
+ } else {
165
+ return { pageCtx: this, isSnapshot: false };
166
+ }
167
+ }
168
+
169
+ moveTo(x, y) {
170
+ if (x !== undefined && x !== null) {
171
+ this.x = x;
172
+ this.availableWidth = this.getCurrentPage().pageSize.width - this.x - this.pageMargins.right;
173
+ }
174
+ if (y !== undefined && y !== null) {
175
+ this.y = y;
176
+ this.availableHeight = this.getCurrentPage().pageSize.height - this.y - this.pageMargins.bottom;
177
+ }
178
+ }
179
+
180
+ moveToRelative(x, y) {
181
+ if (x !== undefined && x !== null) {
182
+ this.x = this.x + x;
183
+ }
184
+ if (y !== undefined && y !== null) {
185
+ this.y = this.y + y;
186
+ }
187
+ }
188
+
189
+ beginDetachedBlock() {
190
+ this.snapshots.push({
191
+ x: this.x,
192
+ y: this.y,
193
+ availableHeight: this.availableHeight,
194
+ availableWidth: this.availableWidth,
195
+ page: this.page,
196
+ lastColumnWidth: this.lastColumnWidth
197
+ });
198
+ }
199
+
200
+ endDetachedBlock() {
201
+ let saved = this.snapshots.pop();
202
+
203
+ this.x = saved.x;
204
+ this.y = saved.y;
205
+ this.availableWidth = saved.availableWidth;
206
+ this.availableHeight = saved.availableHeight;
207
+ this.page = saved.page;
208
+ this.lastColumnWidth = saved.lastColumnWidth;
209
+ }
210
+
211
+ moveToNextPage(pageOrientation) {
212
+ let nextPageIndex = this.page + 1;
213
+ let prevPage = this.page;
214
+ let prevY = this.y;
215
+
216
+ // If we are in a column group
217
+ if (this.snapshots.length > 0) {
218
+ let lastSnapshot = this.snapshots[this.snapshots.length - 1];
219
+ // We have to update prevY accordingly by also taking into consideration
220
+ // the 'y' of cells that don't break page
221
+ if (lastSnapshot.bottomMost && lastSnapshot.bottomMost.y) {
222
+ prevY = Math.max(this.y, lastSnapshot.bottomMost.y);
223
+ }
224
+ }
225
+
226
+ let createNewPage = nextPageIndex >= this.pages.length;
227
+ if (createNewPage) {
228
+ let currentAvailableWidth = this.availableWidth;
229
+ let currentPageOrientation = this.getCurrentPage().pageSize.orientation;
230
+
231
+ let pageSize = getPageSize(this.getCurrentPage(), pageOrientation);
232
+ this.addPage(pageSize, null, this.getCurrentPage().customProperties);
233
+
234
+ if (currentPageOrientation === pageSize.orientation) {
235
+ this.availableWidth = currentAvailableWidth;
236
+ }
237
+ } else {
238
+ this.page = nextPageIndex;
239
+ this.initializePage();
240
+ }
241
+
242
+ return {
243
+ newPageCreated: createNewPage,
244
+ prevPage: prevPage,
245
+ prevY: prevY,
246
+ y: this.y
247
+ };
248
+ }
249
+
250
+ addPage(pageSize, pageMargin = null, customProperties = {}) {
251
+ if (pageMargin !== null) {
252
+ this.pageMargins = pageMargin;
253
+ this.x = pageMargin.left;
254
+ this.availableWidth = pageSize.width - pageMargin.left - pageMargin.right;
255
+ }
256
+
257
+ let page = { items: [], pageSize: pageSize, pageMargins: this.pageMargins, customProperties: customProperties };
258
+ this.pages.push(page);
259
+ this.backgroundLength.push(0);
260
+ this.page = this.pages.length - 1;
261
+ this.initializePage();
262
+
263
+ this.emit('pageAdded', page);
264
+
265
+ return page;
266
+ }
267
+
268
+ getCurrentPage() {
269
+ if (this.page < 0 || this.page >= this.pages.length) {
270
+ return null;
271
+ }
272
+
273
+ return this.pages[this.page];
274
+ }
275
+
276
+ getCurrentPosition() {
277
+ let pageSize = this.getCurrentPage().pageSize;
278
+ let innerHeight = pageSize.height - this.pageMargins.top - this.pageMargins.bottom;
279
+ let innerWidth = pageSize.width - this.pageMargins.left - this.pageMargins.right;
280
+
281
+ return {
282
+ pageNumber: this.page + 1,
283
+ pageOrientation: pageSize.orientation,
284
+ pageInnerHeight: innerHeight,
285
+ pageInnerWidth: innerWidth,
286
+ left: this.x,
287
+ top: this.y,
288
+ verticalRatio: ((this.y - this.pageMargins.top) / innerHeight),
289
+ horizontalRatio: ((this.x - this.pageMargins.left) / innerWidth)
290
+ };
291
+ }
292
+ }
293
+
294
+ function pageOrientation(pageOrientationString, currentPageOrientation) {
295
+ if (pageOrientationString === undefined) {
296
+ return currentPageOrientation;
297
+ } else if (isString(pageOrientationString) && (pageOrientationString.toLowerCase() === 'landscape')) {
298
+ return 'landscape';
299
+ } else {
300
+ return 'portrait';
301
+ }
302
+ }
303
+
304
+ const getPageSize = (currentPage, newPageOrientation) => {
305
+
306
+ newPageOrientation = pageOrientation(newPageOrientation, currentPage.pageSize.orientation);
307
+
308
+ if (newPageOrientation !== currentPage.pageSize.orientation) {
309
+ return {
310
+ orientation: newPageOrientation,
311
+ width: currentPage.pageSize.height,
312
+ height: currentPage.pageSize.width
313
+ };
314
+ } else {
315
+ return {
316
+ orientation: currentPage.pageSize.orientation,
317
+ width: currentPage.pageSize.width,
318
+ height: currentPage.pageSize.height
319
+ };
320
+ }
321
+
322
+ };
323
+
324
+
325
+ function bottomMostContext(c1, c2) {
326
+ let r;
327
+
328
+ if (c1.page > c2.page) {
329
+ r = c1;
330
+ } else if (c2.page > c1.page) {
331
+ r = c2;
332
+ } else {
333
+ r = (c1.y > c2.y) ? c1 : c2;
334
+ }
335
+
336
+ return {
337
+ page: r.page,
338
+ x: r.x,
339
+ y: r.y,
340
+ availableHeight: r.availableHeight,
341
+ availableWidth: r.availableWidth
342
+ };
343
+ }
344
+
345
+ export default DocumentContext;