@flowaccount/pdfmake 0.2.20-staging.2
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/LICENSE +21 -0
- package/README.md +297 -0
- package/build/pdfmake.js +94091 -0
- package/build/pdfmake.min.js +3 -0
- package/build/pdfmake.min.js.map +1 -0
- package/build/vfs_fonts.js +7 -0
- package/package.json +110 -0
- package/src/3rd-party/svg-to-pdfkit/LICENSE +9 -0
- package/src/3rd-party/svg-to-pdfkit/source.js +2552 -0
- package/src/3rd-party/svg-to-pdfkit.js +3 -0
- package/src/browser-extensions/URLBrowserResolver.js +96 -0
- package/src/browser-extensions/pdfMake.js +361 -0
- package/src/browser-extensions/tokenizer-shim.js +16 -0
- package/src/browser-extensions/virtual-fs.js +55 -0
- package/src/columnCalculator.js +157 -0
- package/src/docMeasure.js +831 -0
- package/src/docPreprocessor.js +277 -0
- package/src/documentContext.js +383 -0
- package/src/elementWriter.js +434 -0
- package/src/fontProvider.js +68 -0
- package/src/helpers.js +138 -0
- package/src/imageMeasure.js +70 -0
- package/src/layoutBuilder.js +1537 -0
- package/src/line.js +91 -0
- package/src/pageElementWriter.js +355 -0
- package/src/pdfKitEngine.js +21 -0
- package/src/printer.js +1086 -0
- package/src/qrEnc.js +791 -0
- package/src/standardPageSizes.js +54 -0
- package/src/styleContextStack.js +138 -0
- package/src/svgMeasure.js +70 -0
- package/src/tableProcessor.js +648 -0
- package/src/textDecorator.js +157 -0
- package/src/textTools.js +543 -0
- package/src/traversalTracker.js +47 -0
|
@@ -0,0 +1,831 @@
|
|
|
1
|
+
/*eslint no-unused-vars: ["error", {"args": "none"}]*/
|
|
2
|
+
|
|
3
|
+
'use strict';
|
|
4
|
+
|
|
5
|
+
var TextTools = require('./textTools');
|
|
6
|
+
var StyleContextStack = require('./styleContextStack');
|
|
7
|
+
var ColumnCalculator = require('./columnCalculator');
|
|
8
|
+
var SVGMeasure = require('./svgMeasure');
|
|
9
|
+
var isString = require('./helpers').isString;
|
|
10
|
+
var isNumber = require('./helpers').isNumber;
|
|
11
|
+
var isObject = require('./helpers').isObject;
|
|
12
|
+
var isArray = require('./helpers').isArray;
|
|
13
|
+
var fontStringify = require('./helpers').fontStringify;
|
|
14
|
+
var getNodeId = require('./helpers').getNodeId;
|
|
15
|
+
var pack = require('./helpers').pack;
|
|
16
|
+
var qrEncoder = require('./qrEnc.js');
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* @private
|
|
20
|
+
*/
|
|
21
|
+
function DocMeasure(fontProvider, styleDictionary, defaultStyle, imageMeasure, svgMeasure, tableLayouts, images) {
|
|
22
|
+
this.textTools = new TextTools(fontProvider);
|
|
23
|
+
this.styleStack = new StyleContextStack(styleDictionary, defaultStyle);
|
|
24
|
+
this.imageMeasure = imageMeasure;
|
|
25
|
+
this.svgMeasure = svgMeasure || new SVGMeasure();
|
|
26
|
+
this.tableLayouts = tableLayouts || {};
|
|
27
|
+
this.images = images;
|
|
28
|
+
this.autoImageIndex = 1;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Measures all nodes and sets min/max-width properties required for the second
|
|
33
|
+
* layout-pass.
|
|
34
|
+
* @param {Object} docStructure document-definition-object
|
|
35
|
+
* @return {Object} document-measurement-object
|
|
36
|
+
*/
|
|
37
|
+
DocMeasure.prototype.measureDocument = function (docStructure) {
|
|
38
|
+
return this.measureNode(docStructure);
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
DocMeasure.prototype.measureNode = function (node) {
|
|
42
|
+
|
|
43
|
+
var self = this;
|
|
44
|
+
|
|
45
|
+
return this.styleStack.auto(node, function () {
|
|
46
|
+
// TODO: refactor + rethink whether this is the proper way to handle margins
|
|
47
|
+
node._margin = getNodeMargin(node);
|
|
48
|
+
|
|
49
|
+
if (node.columns) {
|
|
50
|
+
return extendMargins(self.measureColumns(node));
|
|
51
|
+
} else if (node.stack) {
|
|
52
|
+
return extendMargins(self.measureVerticalContainer(node));
|
|
53
|
+
} else if (node.layers) {
|
|
54
|
+
return extendMargins(self.measureLayers(node));
|
|
55
|
+
} else if (node.ul) {
|
|
56
|
+
return extendMargins(self.measureUnorderedList(node));
|
|
57
|
+
} else if (node.ol) {
|
|
58
|
+
return extendMargins(self.measureOrderedList(node));
|
|
59
|
+
} else if (node.table) {
|
|
60
|
+
return extendMargins(self.measureTable(node));
|
|
61
|
+
} else if (node.text !== undefined) {
|
|
62
|
+
return extendMargins(self.measureLeaf(node));
|
|
63
|
+
} else if (node.toc) {
|
|
64
|
+
return extendMargins(self.measureToc(node));
|
|
65
|
+
} else if (node.image) {
|
|
66
|
+
return extendMargins(self.measureImage(node));
|
|
67
|
+
} else if (node.svg) {
|
|
68
|
+
return extendMargins(self.measureSVG(node));
|
|
69
|
+
} else if (node.canvas) {
|
|
70
|
+
return extendMargins(self.measureCanvas(node));
|
|
71
|
+
} else if (node.qr) {
|
|
72
|
+
return extendMargins(self.measureQr(node));
|
|
73
|
+
} else {
|
|
74
|
+
throw 'Unrecognized document structure: ' + JSON.stringify(node, fontStringify);
|
|
75
|
+
}
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
function extendMargins(node) {
|
|
79
|
+
var margin = node._margin;
|
|
80
|
+
|
|
81
|
+
if (margin) {
|
|
82
|
+
node._minWidth += margin[0] + margin[2];
|
|
83
|
+
node._maxWidth += margin[0] + margin[2];
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
return node;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
function getNodeMargin() {
|
|
90
|
+
|
|
91
|
+
function processSingleMargins(node, currentMargin) {
|
|
92
|
+
if (node.marginLeft || node.marginTop || node.marginRight || node.marginBottom) {
|
|
93
|
+
return [
|
|
94
|
+
node.marginLeft || currentMargin[0] || 0,
|
|
95
|
+
node.marginTop || currentMargin[1] || 0,
|
|
96
|
+
node.marginRight || currentMargin[2] || 0,
|
|
97
|
+
node.marginBottom || currentMargin[3] || 0
|
|
98
|
+
];
|
|
99
|
+
}
|
|
100
|
+
return currentMargin;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
function flattenStyleArray(styleArray) {
|
|
104
|
+
var flattenedStyles = {};
|
|
105
|
+
for (var i = styleArray.length - 1; i >= 0; i--) {
|
|
106
|
+
var styleName = styleArray[i];
|
|
107
|
+
var style = self.styleStack.styleDictionary[styleName];
|
|
108
|
+
for (var key in style) {
|
|
109
|
+
if (style.hasOwnProperty(key)) {
|
|
110
|
+
flattenedStyles[key] = style[key];
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
return flattenedStyles;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
function convertMargin(margin) {
|
|
118
|
+
if (isNumber(margin)) {
|
|
119
|
+
margin = [margin, margin, margin, margin];
|
|
120
|
+
} else if (isArray(margin)) {
|
|
121
|
+
if (margin.length === 2) {
|
|
122
|
+
margin = [margin[0], margin[1], margin[0], margin[1]];
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
return margin;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
var margin = [undefined, undefined, undefined, undefined];
|
|
129
|
+
|
|
130
|
+
if (node.style) {
|
|
131
|
+
var styleArray = isArray(node.style) ? node.style : [node.style];
|
|
132
|
+
var flattenedStyleArray = flattenStyleArray(styleArray);
|
|
133
|
+
|
|
134
|
+
if (flattenedStyleArray) {
|
|
135
|
+
margin = processSingleMargins(flattenedStyleArray, margin);
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
if (flattenedStyleArray.margin) {
|
|
139
|
+
margin = convertMargin(flattenedStyleArray.margin);
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
margin = processSingleMargins(node, margin);
|
|
144
|
+
|
|
145
|
+
if (node.margin) {
|
|
146
|
+
margin = convertMargin(node.margin);
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
if (margin[0] === undefined && margin[1] === undefined && margin[2] === undefined && margin[3] === undefined) {
|
|
150
|
+
return null;
|
|
151
|
+
} else {
|
|
152
|
+
return margin;
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
};
|
|
156
|
+
|
|
157
|
+
DocMeasure.prototype.convertIfBase64Image = function (node) {
|
|
158
|
+
if (/^data:image\/(jpeg|jpg|png);base64,/.test(node.image)) {
|
|
159
|
+
var label = '$$pdfmake$$' + this.autoImageIndex++;
|
|
160
|
+
this.images[label] = node.image;
|
|
161
|
+
node.image = label;
|
|
162
|
+
}
|
|
163
|
+
};
|
|
164
|
+
|
|
165
|
+
DocMeasure.prototype.measureImageWithDimensions = function (node, dimensions) {
|
|
166
|
+
if (node.fit) {
|
|
167
|
+
var factor = (dimensions.width / dimensions.height > node.fit[0] / node.fit[1]) ? node.fit[0] / dimensions.width : node.fit[1] / dimensions.height;
|
|
168
|
+
node._width = node._minWidth = node._maxWidth = dimensions.width * factor;
|
|
169
|
+
node._height = dimensions.height * factor;
|
|
170
|
+
} else if (node.cover) {
|
|
171
|
+
node._width = node._minWidth = node._maxWidth = node.cover.width;
|
|
172
|
+
node._height = node._minHeight = node._maxHeight = node.cover.height;
|
|
173
|
+
} else {
|
|
174
|
+
node._width = node._minWidth = node._maxWidth = node.width || dimensions.width;
|
|
175
|
+
node._height = node.height || (dimensions.height * node._width / dimensions.width);
|
|
176
|
+
|
|
177
|
+
if (isNumber(node.maxWidth) && node.maxWidth < node._width) {
|
|
178
|
+
node._width = node._minWidth = node._maxWidth = node.maxWidth;
|
|
179
|
+
node._height = node._width * dimensions.height / dimensions.width;
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
if (isNumber(node.maxHeight) && node.maxHeight < node._height) {
|
|
183
|
+
node._height = node.maxHeight;
|
|
184
|
+
node._width = node._minWidth = node._maxWidth = node._height * dimensions.width / dimensions.height;
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
if (isNumber(node.minWidth) && node.minWidth > node._width) {
|
|
188
|
+
node._width = node._minWidth = node._maxWidth = node.minWidth;
|
|
189
|
+
node._height = node._width * dimensions.height / dimensions.width;
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
if (isNumber(node.minHeight) && node.minHeight > node._height) {
|
|
193
|
+
node._height = node.minHeight;
|
|
194
|
+
node._width = node._minWidth = node._maxWidth = node._height * dimensions.width / dimensions.height;
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
node._alignment = this.styleStack.getProperty('alignment');
|
|
199
|
+
};
|
|
200
|
+
|
|
201
|
+
DocMeasure.prototype.measureImage = function (node) {
|
|
202
|
+
if (this.images) {
|
|
203
|
+
this.convertIfBase64Image(node);
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
var dimensions = this.imageMeasure.measureImage(node.image);
|
|
207
|
+
|
|
208
|
+
this.measureImageWithDimensions(node, dimensions);
|
|
209
|
+
|
|
210
|
+
return node;
|
|
211
|
+
};
|
|
212
|
+
|
|
213
|
+
DocMeasure.prototype.measureSVG = function (node) {
|
|
214
|
+
var dimensions = this.svgMeasure.measureSVG(node.svg);
|
|
215
|
+
|
|
216
|
+
this.measureImageWithDimensions(node, dimensions);
|
|
217
|
+
|
|
218
|
+
node.font = this.styleStack.getProperty('font');
|
|
219
|
+
|
|
220
|
+
// scale SVG based on final dimension
|
|
221
|
+
node.svg = this.svgMeasure.writeDimensions(node.svg, {
|
|
222
|
+
width: node._width,
|
|
223
|
+
height: node._height
|
|
224
|
+
});
|
|
225
|
+
|
|
226
|
+
return node;
|
|
227
|
+
};
|
|
228
|
+
|
|
229
|
+
DocMeasure.prototype.measureLeaf = function (node) {
|
|
230
|
+
|
|
231
|
+
if (node._textRef && node._textRef._textNodeRef.text) {
|
|
232
|
+
node.text = node._textRef._textNodeRef.text;
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
// Make sure style properties of the node itself are considered when building inlines.
|
|
236
|
+
// We could also just pass [node] to buildInlines, but that fails for bullet points.
|
|
237
|
+
var styleStack = this.styleStack.clone();
|
|
238
|
+
styleStack.push(node);
|
|
239
|
+
|
|
240
|
+
var data = this.textTools.buildInlines(node.text, styleStack);
|
|
241
|
+
|
|
242
|
+
node._inlines = data.items;
|
|
243
|
+
node._minWidth = data.minWidth;
|
|
244
|
+
node._maxWidth = data.maxWidth;
|
|
245
|
+
|
|
246
|
+
return node;
|
|
247
|
+
};
|
|
248
|
+
|
|
249
|
+
DocMeasure.prototype.measureToc = function (node) {
|
|
250
|
+
if (node.toc.title) {
|
|
251
|
+
node.toc.title = this.measureNode(node.toc.title);
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
if (node.toc._items.length > 0) {
|
|
255
|
+
var items = node.toc._items;
|
|
256
|
+
var body = [];
|
|
257
|
+
var textStyle = node.toc.textStyle || {};
|
|
258
|
+
var numberStyle = node.toc.numberStyle || textStyle;
|
|
259
|
+
var textMargin = node.toc.textMargin || [0, 0, 0, 0];
|
|
260
|
+
for (var i = 0, l = items.length; i < l; i++) {
|
|
261
|
+
var tocItem = items[i];
|
|
262
|
+
var textNodeRef = tocItem._textNodeRef;
|
|
263
|
+
var lineStyle = (textNodeRef && textNodeRef.tocStyle) || textStyle;
|
|
264
|
+
var lineMargin = (textNodeRef && textNodeRef.tocMargin) || textMargin;
|
|
265
|
+
var lineNumberStyle = (textNodeRef && textNodeRef.tocNumberStyle) || numberStyle;
|
|
266
|
+
var destination = getNodeId(tocItem._nodeRef);
|
|
267
|
+
body.push([
|
|
268
|
+
{ text: textNodeRef.text, linkToDestination: destination, alignment: 'left', style: lineStyle, margin: lineMargin },
|
|
269
|
+
{ text: '00000', linkToDestination: destination, alignment: 'right', _tocItemRef: tocItem._nodeRef, style: lineNumberStyle, margin: [0, lineMargin[1], 0, lineMargin[3]] }
|
|
270
|
+
]);
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
node.toc._table = {
|
|
274
|
+
table: {
|
|
275
|
+
dontBreakRows: true,
|
|
276
|
+
widths: ['*', 'auto'],
|
|
277
|
+
body: body
|
|
278
|
+
},
|
|
279
|
+
layout: 'noBorders'
|
|
280
|
+
};
|
|
281
|
+
|
|
282
|
+
node.toc._table = this.measureNode(node.toc._table);
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
return node;
|
|
286
|
+
};
|
|
287
|
+
|
|
288
|
+
DocMeasure.prototype.measureVerticalContainer = function (node) {
|
|
289
|
+
var items = node.stack;
|
|
290
|
+
|
|
291
|
+
node._minWidth = 0;
|
|
292
|
+
node._maxWidth = 0;
|
|
293
|
+
|
|
294
|
+
for (var i = 0, l = items.length; i < l; i++) {
|
|
295
|
+
items[i] = this.measureNode(items[i]);
|
|
296
|
+
|
|
297
|
+
node._minWidth = Math.max(node._minWidth, items[i]._minWidth);
|
|
298
|
+
node._maxWidth = Math.max(node._maxWidth, items[i]._maxWidth);
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
return node;
|
|
302
|
+
};
|
|
303
|
+
|
|
304
|
+
DocMeasure.prototype.measureLayers = function (node) {
|
|
305
|
+
var items = node.layers;
|
|
306
|
+
|
|
307
|
+
node._minWidth = 0;
|
|
308
|
+
node._maxWidth = 0;
|
|
309
|
+
|
|
310
|
+
for (var i = 0, l = items.length; i < l; i++) {
|
|
311
|
+
items[i] = this.measureNode(items[i]);
|
|
312
|
+
|
|
313
|
+
node._minWidth = Math.max(node._minWidth, items[i]._minWidth);
|
|
314
|
+
node._maxWidth = Math.max(node._maxWidth, items[i]._maxWidth);
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
return node;
|
|
318
|
+
};
|
|
319
|
+
|
|
320
|
+
DocMeasure.prototype.gapSizeForList = function () {
|
|
321
|
+
return this.textTools.sizeOfString('9. ', this.styleStack);
|
|
322
|
+
};
|
|
323
|
+
|
|
324
|
+
DocMeasure.prototype.buildUnorderedMarker = function (styleStack, gapSize, type) {
|
|
325
|
+
function buildDisc(gapSize, color) {
|
|
326
|
+
// TODO: ascender-based calculations
|
|
327
|
+
var radius = gapSize.fontSize / 6;
|
|
328
|
+
return {
|
|
329
|
+
canvas: [{
|
|
330
|
+
x: radius,
|
|
331
|
+
y: (gapSize.height / gapSize.lineHeight) + gapSize.descender - gapSize.fontSize / 3,
|
|
332
|
+
r1: radius,
|
|
333
|
+
r2: radius,
|
|
334
|
+
type: 'ellipse',
|
|
335
|
+
color: color
|
|
336
|
+
}]
|
|
337
|
+
};
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
function buildSquare(gapSize, color) {
|
|
341
|
+
// TODO: ascender-based calculations
|
|
342
|
+
var size = gapSize.fontSize / 3;
|
|
343
|
+
return {
|
|
344
|
+
canvas: [{
|
|
345
|
+
x: 0,
|
|
346
|
+
y: (gapSize.height / gapSize.lineHeight) + gapSize.descender - (gapSize.fontSize / 3) - (size / 2),
|
|
347
|
+
h: size,
|
|
348
|
+
w: size,
|
|
349
|
+
type: 'rect',
|
|
350
|
+
color: color
|
|
351
|
+
}]
|
|
352
|
+
};
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
function buildCircle(gapSize, color) {
|
|
356
|
+
// TODO: ascender-based calculations
|
|
357
|
+
var radius = gapSize.fontSize / 6;
|
|
358
|
+
return {
|
|
359
|
+
canvas: [{
|
|
360
|
+
x: radius,
|
|
361
|
+
y: (gapSize.height / gapSize.lineHeight) + gapSize.descender - gapSize.fontSize / 3,
|
|
362
|
+
r1: radius,
|
|
363
|
+
r2: radius,
|
|
364
|
+
type: 'ellipse',
|
|
365
|
+
lineColor: color
|
|
366
|
+
}]
|
|
367
|
+
};
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
var marker;
|
|
371
|
+
var color = styleStack.getProperty('markerColor') || styleStack.getProperty('color') || 'black';
|
|
372
|
+
|
|
373
|
+
switch (type) {
|
|
374
|
+
case 'circle':
|
|
375
|
+
marker = buildCircle(gapSize, color);
|
|
376
|
+
break;
|
|
377
|
+
|
|
378
|
+
case 'square':
|
|
379
|
+
marker = buildSquare(gapSize, color);
|
|
380
|
+
break;
|
|
381
|
+
|
|
382
|
+
case 'none':
|
|
383
|
+
marker = {};
|
|
384
|
+
break;
|
|
385
|
+
|
|
386
|
+
case 'disc':
|
|
387
|
+
default:
|
|
388
|
+
marker = buildDisc(gapSize, color);
|
|
389
|
+
break;
|
|
390
|
+
}
|
|
391
|
+
|
|
392
|
+
marker._minWidth = marker._maxWidth = gapSize.width;
|
|
393
|
+
marker._minHeight = marker._maxHeight = gapSize.height;
|
|
394
|
+
|
|
395
|
+
return marker;
|
|
396
|
+
};
|
|
397
|
+
|
|
398
|
+
DocMeasure.prototype.buildOrderedMarker = function (counter, styleStack, type, separator) {
|
|
399
|
+
function prepareAlpha(counter) {
|
|
400
|
+
function toAlpha(num) {
|
|
401
|
+
return (num >= 26 ? toAlpha((num / 26 >> 0) - 1) : '') + 'abcdefghijklmnopqrstuvwxyz'[num % 26 >> 0];
|
|
402
|
+
}
|
|
403
|
+
|
|
404
|
+
if (counter < 1) {
|
|
405
|
+
return counter.toString();
|
|
406
|
+
}
|
|
407
|
+
|
|
408
|
+
return toAlpha(counter - 1);
|
|
409
|
+
}
|
|
410
|
+
|
|
411
|
+
function prepareRoman(counter) {
|
|
412
|
+
if (counter < 1 || counter > 4999) {
|
|
413
|
+
return counter.toString();
|
|
414
|
+
}
|
|
415
|
+
var num = counter;
|
|
416
|
+
var lookup = { M: 1000, CM: 900, D: 500, CD: 400, C: 100, XC: 90, L: 50, XL: 40, X: 10, IX: 9, V: 5, IV: 4, I: 1 }, roman = '', i;
|
|
417
|
+
for (i in lookup) {
|
|
418
|
+
while (num >= lookup[i]) {
|
|
419
|
+
roman += i;
|
|
420
|
+
num -= lookup[i];
|
|
421
|
+
}
|
|
422
|
+
}
|
|
423
|
+
return roman;
|
|
424
|
+
}
|
|
425
|
+
|
|
426
|
+
function prepareDecimal(counter) {
|
|
427
|
+
return counter.toString();
|
|
428
|
+
}
|
|
429
|
+
|
|
430
|
+
var counterText;
|
|
431
|
+
switch (type) {
|
|
432
|
+
case 'none':
|
|
433
|
+
counterText = null;
|
|
434
|
+
break;
|
|
435
|
+
|
|
436
|
+
case 'upper-alpha':
|
|
437
|
+
counterText = prepareAlpha(counter).toUpperCase();
|
|
438
|
+
break;
|
|
439
|
+
|
|
440
|
+
case 'lower-alpha':
|
|
441
|
+
counterText = prepareAlpha(counter);
|
|
442
|
+
break;
|
|
443
|
+
|
|
444
|
+
case 'upper-roman':
|
|
445
|
+
counterText = prepareRoman(counter);
|
|
446
|
+
break;
|
|
447
|
+
|
|
448
|
+
case 'lower-roman':
|
|
449
|
+
counterText = prepareRoman(counter).toLowerCase();
|
|
450
|
+
break;
|
|
451
|
+
|
|
452
|
+
case 'decimal':
|
|
453
|
+
default:
|
|
454
|
+
counterText = prepareDecimal(counter);
|
|
455
|
+
break;
|
|
456
|
+
}
|
|
457
|
+
|
|
458
|
+
if (counterText === null) {
|
|
459
|
+
return {};
|
|
460
|
+
}
|
|
461
|
+
|
|
462
|
+
if (separator) {
|
|
463
|
+
if (isArray(separator)) {
|
|
464
|
+
if (separator[0]) {
|
|
465
|
+
counterText = separator[0] + counterText;
|
|
466
|
+
}
|
|
467
|
+
|
|
468
|
+
if (separator[1]) {
|
|
469
|
+
counterText += separator[1];
|
|
470
|
+
}
|
|
471
|
+
counterText += ' ';
|
|
472
|
+
} else {
|
|
473
|
+
counterText += separator + ' ';
|
|
474
|
+
}
|
|
475
|
+
}
|
|
476
|
+
|
|
477
|
+
var textArray = { text: counterText };
|
|
478
|
+
var markerColor = styleStack.getProperty('markerColor');
|
|
479
|
+
if (markerColor) {
|
|
480
|
+
textArray.color = markerColor;
|
|
481
|
+
}
|
|
482
|
+
|
|
483
|
+
return { _inlines: this.textTools.buildInlines(textArray, styleStack).items };
|
|
484
|
+
};
|
|
485
|
+
|
|
486
|
+
DocMeasure.prototype.measureUnorderedList = function (node) {
|
|
487
|
+
var style = this.styleStack.clone();
|
|
488
|
+
var items = node.ul;
|
|
489
|
+
node.type = node.type || 'disc';
|
|
490
|
+
node._gapSize = this.gapSizeForList();
|
|
491
|
+
node._minWidth = 0;
|
|
492
|
+
node._maxWidth = 0;
|
|
493
|
+
|
|
494
|
+
for (var i = 0, l = items.length; i < l; i++) {
|
|
495
|
+
var item = items[i] = this.measureNode(items[i]);
|
|
496
|
+
|
|
497
|
+
if (!item.ol && !item.ul) {
|
|
498
|
+
item.listMarker = this.buildUnorderedMarker(style, node._gapSize, item.listType || node.type);
|
|
499
|
+
}
|
|
500
|
+
|
|
501
|
+
node._minWidth = Math.max(node._minWidth, items[i]._minWidth + node._gapSize.width);
|
|
502
|
+
node._maxWidth = Math.max(node._maxWidth, items[i]._maxWidth + node._gapSize.width);
|
|
503
|
+
}
|
|
504
|
+
|
|
505
|
+
return node;
|
|
506
|
+
};
|
|
507
|
+
|
|
508
|
+
DocMeasure.prototype.measureOrderedList = function (node) {
|
|
509
|
+
var style = this.styleStack.clone();
|
|
510
|
+
var items = node.ol;
|
|
511
|
+
node.type = node.type || 'decimal';
|
|
512
|
+
node.separator = node.separator || '.';
|
|
513
|
+
node.reversed = node.reversed || false;
|
|
514
|
+
if (!isNumber(node.start)) {
|
|
515
|
+
node.start = node.reversed ? items.length : 1;
|
|
516
|
+
}
|
|
517
|
+
node._gapSize = this.gapSizeForList();
|
|
518
|
+
node._minWidth = 0;
|
|
519
|
+
node._maxWidth = 0;
|
|
520
|
+
|
|
521
|
+
var counter = node.start;
|
|
522
|
+
for (var i = 0, l = items.length; i < l; i++) {
|
|
523
|
+
var item = items[i] = this.measureNode(items[i]);
|
|
524
|
+
|
|
525
|
+
if (!item.ol && !item.ul) {
|
|
526
|
+
var counterValue = isNumber(item.counter) ? item.counter : counter;
|
|
527
|
+
item.listMarker = this.buildOrderedMarker(counterValue, style, item.listType || node.type, node.separator);
|
|
528
|
+
if (item.listMarker._inlines) {
|
|
529
|
+
node._gapSize.width = Math.max(node._gapSize.width, item.listMarker._inlines[0].width);
|
|
530
|
+
}
|
|
531
|
+
|
|
532
|
+
if (node.reversed) {
|
|
533
|
+
counter--;
|
|
534
|
+
} else {
|
|
535
|
+
counter++;
|
|
536
|
+
}
|
|
537
|
+
}
|
|
538
|
+
|
|
539
|
+
node._minWidth = Math.max(node._minWidth, items[i]._minWidth);
|
|
540
|
+
node._maxWidth = Math.max(node._maxWidth, items[i]._maxWidth);
|
|
541
|
+
}
|
|
542
|
+
|
|
543
|
+
node._minWidth += node._gapSize.width;
|
|
544
|
+
node._maxWidth += node._gapSize.width;
|
|
545
|
+
|
|
546
|
+
for (var i = 0, l = items.length; i < l; i++) {
|
|
547
|
+
var item = items[i];
|
|
548
|
+
if (!item.ol && !item.ul) {
|
|
549
|
+
item.listMarker._minWidth = item.listMarker._maxWidth = node._gapSize.width;
|
|
550
|
+
}
|
|
551
|
+
}
|
|
552
|
+
|
|
553
|
+
return node;
|
|
554
|
+
};
|
|
555
|
+
|
|
556
|
+
DocMeasure.prototype.measureColumns = function (node) {
|
|
557
|
+
var columns = node.columns;
|
|
558
|
+
node._gap = this.styleStack.getProperty('columnGap') || 0;
|
|
559
|
+
|
|
560
|
+
for (var i = 0, l = columns.length; i < l; i++) {
|
|
561
|
+
columns[i] = this.measureNode(columns[i]);
|
|
562
|
+
}
|
|
563
|
+
|
|
564
|
+
var measures = ColumnCalculator.measureMinMax(columns);
|
|
565
|
+
|
|
566
|
+
var numGaps = (columns.length > 0) ? (columns.length - 1) : 0;
|
|
567
|
+
node._minWidth = measures.min + node._gap * numGaps;
|
|
568
|
+
node._maxWidth = measures.max + node._gap * numGaps;
|
|
569
|
+
|
|
570
|
+
return node;
|
|
571
|
+
};
|
|
572
|
+
|
|
573
|
+
DocMeasure.prototype.measureTable = function (node) {
|
|
574
|
+
extendTableWidths(node);
|
|
575
|
+
node._layout = getLayout(this.tableLayouts);
|
|
576
|
+
node._offsets = getOffsets(node._layout);
|
|
577
|
+
|
|
578
|
+
var colSpans = [];
|
|
579
|
+
var col, row, cols, rows;
|
|
580
|
+
|
|
581
|
+
if (node.table.body[0]) {
|
|
582
|
+
for (col = 0, cols = node.table.body[0].length; col < cols; col++) {
|
|
583
|
+
var c = node.table.widths[col];
|
|
584
|
+
c._minWidth = 0;
|
|
585
|
+
c._maxWidth = 0;
|
|
586
|
+
|
|
587
|
+
for (row = 0, rows = node.table.body.length; row < rows; row++) {
|
|
588
|
+
var rowData = node.table.body[row];
|
|
589
|
+
var data = rowData[col];
|
|
590
|
+
if (data === undefined) {
|
|
591
|
+
console.error('Malformed table row ', rowData, 'in node ', node);
|
|
592
|
+
throw new Error('Malformed table row, a cell is undefined.');
|
|
593
|
+
}
|
|
594
|
+
if (data === null) { // transform to object
|
|
595
|
+
data = '';
|
|
596
|
+
}
|
|
597
|
+
|
|
598
|
+
if (!data._span) {
|
|
599
|
+
data = rowData[col] = this.styleStack.auto(data, measureCb(this, data));
|
|
600
|
+
|
|
601
|
+
if (data.colSpan && data.colSpan > 1) {
|
|
602
|
+
markSpans(rowData, col, data.colSpan);
|
|
603
|
+
colSpans.push({ col: col, span: data.colSpan, minWidth: data._minWidth, maxWidth: data._maxWidth });
|
|
604
|
+
} else {
|
|
605
|
+
c._minWidth = Math.max(c._minWidth, data._minWidth);
|
|
606
|
+
c._maxWidth = Math.max(c._maxWidth, data._maxWidth);
|
|
607
|
+
}
|
|
608
|
+
}
|
|
609
|
+
|
|
610
|
+
if (data.rowSpan && data.rowSpan > 1) {
|
|
611
|
+
markVSpans(node.table, row, col, data.rowSpan);
|
|
612
|
+
}
|
|
613
|
+
}
|
|
614
|
+
}
|
|
615
|
+
}
|
|
616
|
+
|
|
617
|
+
extendWidthsForColSpans();
|
|
618
|
+
|
|
619
|
+
var measures = ColumnCalculator.measureMinMax(node.table.widths);
|
|
620
|
+
|
|
621
|
+
node._minWidth = measures.min + node._offsets.total;
|
|
622
|
+
node._maxWidth = measures.max + node._offsets.total;
|
|
623
|
+
|
|
624
|
+
return node;
|
|
625
|
+
|
|
626
|
+
function measureCb(_this, data) {
|
|
627
|
+
return function () {
|
|
628
|
+
if (isObject(data)) {
|
|
629
|
+
data.fillColor = _this.styleStack.getProperty('fillColor');
|
|
630
|
+
data.fillOpacity = _this.styleStack.getProperty('fillOpacity');
|
|
631
|
+
}
|
|
632
|
+
return _this.measureNode(data);
|
|
633
|
+
};
|
|
634
|
+
}
|
|
635
|
+
|
|
636
|
+
function getLayout(tableLayouts) {
|
|
637
|
+
var layout = node.layout;
|
|
638
|
+
|
|
639
|
+
if (isString(layout)) {
|
|
640
|
+
layout = tableLayouts[layout];
|
|
641
|
+
}
|
|
642
|
+
|
|
643
|
+
var defaultLayout = {
|
|
644
|
+
hLineWidth: function (i, node) {
|
|
645
|
+
return 1;
|
|
646
|
+
},
|
|
647
|
+
vLineWidth: function (i, node) {
|
|
648
|
+
return 1;
|
|
649
|
+
},
|
|
650
|
+
hLineColor: function (i, node) {
|
|
651
|
+
return 'black';
|
|
652
|
+
},
|
|
653
|
+
vLineColor: function (i, node) {
|
|
654
|
+
return 'black';
|
|
655
|
+
},
|
|
656
|
+
hLineStyle: function (i, node) {
|
|
657
|
+
return null;
|
|
658
|
+
},
|
|
659
|
+
vLineStyle: function (i, node) {
|
|
660
|
+
return null;
|
|
661
|
+
},
|
|
662
|
+
paddingLeft: function (i, node) {
|
|
663
|
+
return 4;
|
|
664
|
+
},
|
|
665
|
+
paddingRight: function (i, node) {
|
|
666
|
+
return 4;
|
|
667
|
+
},
|
|
668
|
+
paddingTop: function (i, node) {
|
|
669
|
+
return 2;
|
|
670
|
+
},
|
|
671
|
+
paddingBottom: function (i, node) {
|
|
672
|
+
return 2;
|
|
673
|
+
},
|
|
674
|
+
fillColor: function (i, node) {
|
|
675
|
+
return null;
|
|
676
|
+
},
|
|
677
|
+
fillOpacity: function (i, node) {
|
|
678
|
+
return 1;
|
|
679
|
+
},
|
|
680
|
+
defaultBorder: true
|
|
681
|
+
};
|
|
682
|
+
|
|
683
|
+
return pack(defaultLayout, layout);
|
|
684
|
+
}
|
|
685
|
+
|
|
686
|
+
function getOffsets(layout) {
|
|
687
|
+
var offsets = [];
|
|
688
|
+
var totalOffset = 0;
|
|
689
|
+
var prevRightPadding = 0;
|
|
690
|
+
|
|
691
|
+
for (var i = 0, l = node.table.widths.length; i < l; i++) {
|
|
692
|
+
var lOffset = prevRightPadding + layout.vLineWidth(i, node) + layout.paddingLeft(i, node);
|
|
693
|
+
offsets.push(lOffset);
|
|
694
|
+
totalOffset += lOffset;
|
|
695
|
+
prevRightPadding = layout.paddingRight(i, node);
|
|
696
|
+
}
|
|
697
|
+
|
|
698
|
+
totalOffset += prevRightPadding + layout.vLineWidth(node.table.widths.length, node);
|
|
699
|
+
|
|
700
|
+
return {
|
|
701
|
+
total: totalOffset,
|
|
702
|
+
offsets: offsets
|
|
703
|
+
};
|
|
704
|
+
}
|
|
705
|
+
|
|
706
|
+
function extendWidthsForColSpans() {
|
|
707
|
+
var q, j;
|
|
708
|
+
|
|
709
|
+
for (var i = 0, l = colSpans.length; i < l; i++) {
|
|
710
|
+
var span = colSpans[i];
|
|
711
|
+
|
|
712
|
+
var currentMinMax = getMinMax(span.col, span.span, node._offsets);
|
|
713
|
+
var minDifference = span.minWidth - currentMinMax.minWidth;
|
|
714
|
+
var maxDifference = span.maxWidth - currentMinMax.maxWidth;
|
|
715
|
+
|
|
716
|
+
if (minDifference > 0) {
|
|
717
|
+
q = minDifference / span.span;
|
|
718
|
+
|
|
719
|
+
for (j = 0; j < span.span; j++) {
|
|
720
|
+
node.table.widths[span.col + j]._minWidth += q;
|
|
721
|
+
}
|
|
722
|
+
}
|
|
723
|
+
|
|
724
|
+
if (maxDifference > 0) {
|
|
725
|
+
q = maxDifference / span.span;
|
|
726
|
+
|
|
727
|
+
for (j = 0; j < span.span; j++) {
|
|
728
|
+
node.table.widths[span.col + j]._maxWidth += q;
|
|
729
|
+
}
|
|
730
|
+
}
|
|
731
|
+
}
|
|
732
|
+
}
|
|
733
|
+
|
|
734
|
+
function getMinMax(col, span, offsets) {
|
|
735
|
+
var result = { minWidth: 0, maxWidth: 0 };
|
|
736
|
+
|
|
737
|
+
for (var i = 0; i < span; i++) {
|
|
738
|
+
result.minWidth += node.table.widths[col + i]._minWidth + (i ? offsets.offsets[col + i] : 0);
|
|
739
|
+
result.maxWidth += node.table.widths[col + i]._maxWidth + (i ? offsets.offsets[col + i] : 0);
|
|
740
|
+
}
|
|
741
|
+
|
|
742
|
+
return result;
|
|
743
|
+
}
|
|
744
|
+
|
|
745
|
+
function markSpans(rowData, col, span) {
|
|
746
|
+
for (var i = 1; i < span; i++) {
|
|
747
|
+
rowData[col + i] = {
|
|
748
|
+
_span: true,
|
|
749
|
+
_minWidth: 0,
|
|
750
|
+
_maxWidth: 0,
|
|
751
|
+
rowSpan: rowData[col].rowSpan
|
|
752
|
+
};
|
|
753
|
+
}
|
|
754
|
+
}
|
|
755
|
+
|
|
756
|
+
function markVSpans(table, row, col, span) {
|
|
757
|
+
for (var i = 1; i < span; i++) {
|
|
758
|
+
table.body[row + i][col] = {
|
|
759
|
+
_span: true,
|
|
760
|
+
_minWidth: 0,
|
|
761
|
+
_maxWidth: 0,
|
|
762
|
+
fillColor: table.body[row][col].fillColor,
|
|
763
|
+
fillOpacity: table.body[row][col].fillOpacity
|
|
764
|
+
};
|
|
765
|
+
}
|
|
766
|
+
}
|
|
767
|
+
|
|
768
|
+
function extendTableWidths(node) {
|
|
769
|
+
if (!node.table.widths) {
|
|
770
|
+
node.table.widths = 'auto';
|
|
771
|
+
}
|
|
772
|
+
|
|
773
|
+
if (isString(node.table.widths)) {
|
|
774
|
+
node.table.widths = [node.table.widths];
|
|
775
|
+
|
|
776
|
+
while (node.table.widths.length < node.table.body[0].length) {
|
|
777
|
+
node.table.widths.push(node.table.widths[node.table.widths.length - 1]);
|
|
778
|
+
}
|
|
779
|
+
}
|
|
780
|
+
|
|
781
|
+
for (var i = 0, l = node.table.widths.length; i < l; i++) {
|
|
782
|
+
var w = node.table.widths[i];
|
|
783
|
+
if (isNumber(w) || isString(w)) {
|
|
784
|
+
node.table.widths[i] = { width: w };
|
|
785
|
+
}
|
|
786
|
+
}
|
|
787
|
+
}
|
|
788
|
+
};
|
|
789
|
+
|
|
790
|
+
DocMeasure.prototype.measureCanvas = function (node) {
|
|
791
|
+
var w = 0, h = 0;
|
|
792
|
+
|
|
793
|
+
for (var i = 0, l = node.canvas.length; i < l; i++) {
|
|
794
|
+
var vector = node.canvas[i];
|
|
795
|
+
|
|
796
|
+
switch (vector.type) {
|
|
797
|
+
case 'ellipse':
|
|
798
|
+
w = Math.max(w, vector.x + vector.r1);
|
|
799
|
+
h = Math.max(h, vector.y + vector.r2);
|
|
800
|
+
break;
|
|
801
|
+
case 'rect':
|
|
802
|
+
w = Math.max(w, vector.x + vector.w);
|
|
803
|
+
h = Math.max(h, vector.y + vector.h);
|
|
804
|
+
break;
|
|
805
|
+
case 'line':
|
|
806
|
+
w = Math.max(w, vector.x1, vector.x2);
|
|
807
|
+
h = Math.max(h, vector.y1, vector.y2);
|
|
808
|
+
break;
|
|
809
|
+
case 'polyline':
|
|
810
|
+
for (var i2 = 0, l2 = vector.points.length; i2 < l2; i2++) {
|
|
811
|
+
w = Math.max(w, vector.points[i2].x);
|
|
812
|
+
h = Math.max(h, vector.points[i2].y);
|
|
813
|
+
}
|
|
814
|
+
break;
|
|
815
|
+
}
|
|
816
|
+
}
|
|
817
|
+
|
|
818
|
+
node._minWidth = node._maxWidth = w;
|
|
819
|
+
node._minHeight = node._maxHeight = h;
|
|
820
|
+
node._alignment = this.styleStack.getProperty('alignment');
|
|
821
|
+
|
|
822
|
+
return node;
|
|
823
|
+
};
|
|
824
|
+
|
|
825
|
+
DocMeasure.prototype.measureQr = function (node) {
|
|
826
|
+
node = qrEncoder.measure(node);
|
|
827
|
+
node._alignment = this.styleStack.getProperty('alignment');
|
|
828
|
+
return node;
|
|
829
|
+
};
|
|
830
|
+
|
|
831
|
+
module.exports = DocMeasure;
|