@muhammara/native-core 7.0.0-beta.3 → 7.0.0-beta.4
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/lib/Recipe.js +7 -2
- package/lib/recipe/annotation.js +19 -5
- package/lib/recipe/appendPage.js +6 -1
- package/lib/recipe/htmlToTextObjects.js +37 -1
- package/lib/recipe/page.js +16 -13
- package/lib/recipe/parameters.js +3 -1
- package/lib/recipe/table.js +223 -169
- package/lib/recipe/text.helper.js +4 -2
- package/lib/recipe/text.js +130 -63
- package/lib/recipe/utils.js +52 -0
- package/lib/recipe/vector.helper.js +2 -7
- package/lib/recipe/vector.js +0 -2
- package/muhammara.d.ts +29 -8
- package/package.json +1 -1
package/lib/recipe/table.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
}
|
|
1
|
+
var { htmlToTextObjects } = require("./htmlToTextObjects");
|
|
2
|
+
var { cloneOptions: clone } = require("./utils");
|
|
4
3
|
|
|
4
|
+
/** Converts a table cell style into text options. */
|
|
5
5
|
function getCellOptions(options, cell = "cell") {
|
|
6
|
-
|
|
6
|
+
var cellOptions = clone(options);
|
|
7
7
|
|
|
8
8
|
if (cellOptions[cell]) {
|
|
9
9
|
// convert cell options to textBox options
|
|
@@ -13,65 +13,117 @@ function getCellOptions(options, cell = "cell") {
|
|
|
13
13
|
return cellOptions;
|
|
14
14
|
}
|
|
15
15
|
|
|
16
|
+
/** Measures the same text and outer box height that text() will draw. */
|
|
16
17
|
function getCellHeight(self, text, column, options) {
|
|
17
|
-
|
|
18
|
-
|
|
18
|
+
var colOptions = self._merge(options, { textBox: { width: column.width } });
|
|
19
|
+
var originCoord = self._calibrateCoordinate(
|
|
19
20
|
column.x,
|
|
20
21
|
column.y,
|
|
21
22
|
0,
|
|
22
23
|
0,
|
|
23
24
|
self.pageNumber,
|
|
24
25
|
);
|
|
25
|
-
|
|
26
|
+
var pathOptions = self._getPathOptions(
|
|
26
27
|
colOptions,
|
|
27
28
|
originCoord.nx,
|
|
28
29
|
originCoord.ny,
|
|
29
30
|
);
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
31
|
+
pathOptions.html = colOptions.html;
|
|
32
|
+
var textObjects = colOptions.html
|
|
33
|
+
? htmlToTextObjects(text, colOptions)
|
|
34
|
+
: self._makeTextObject(text, pathOptions.size, colOptions);
|
|
35
|
+
var textBox = self._makeTextBox(colOptions);
|
|
36
|
+
var { textHeight } = self._layoutText(textObjects, textBox, pathOptions);
|
|
37
|
+
|
|
38
|
+
return (
|
|
39
|
+
textBox.height ||
|
|
40
|
+
Math.max(
|
|
41
|
+
textBox.minHeight,
|
|
42
|
+
textHeight + textBox.paddingTop + textBox.paddingBottom,
|
|
43
|
+
)
|
|
44
|
+
);
|
|
35
45
|
}
|
|
36
46
|
|
|
47
|
+
/** Draws a completed table segment without duplicating its bottom edge. */
|
|
37
48
|
function drawTableBorder(self, x, y, width, height, rowLines, options) {
|
|
38
|
-
|
|
39
|
-
|
|
49
|
+
// A segment without rows has nothing to enclose.
|
|
50
|
+
if (!options.border || height <= 0) {
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
53
|
+
var borderOptions = Object.assign(
|
|
54
|
+
{},
|
|
55
|
+
options.border === true ? {} : options.border,
|
|
56
|
+
// Keep borders from extending outside of the enclosing box.
|
|
57
|
+
{ lineCap: "butt" },
|
|
58
|
+
);
|
|
59
|
+
if (!borderOptions.width) {
|
|
60
|
+
borderOptions.width = 0.5;
|
|
61
|
+
}
|
|
40
62
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
63
|
+
self.rectangle(x, y, width, height, borderOptions);
|
|
64
|
+
var columns = self._layouts["_table_"];
|
|
65
|
+
|
|
66
|
+
// Draw verticals
|
|
67
|
+
for (var index = 0; index < columns.length - 1; index++) {
|
|
68
|
+
var column = columns[index];
|
|
69
|
+
self.line(
|
|
70
|
+
[
|
|
71
|
+
[column.x + column.width, y],
|
|
72
|
+
[column.x + column.width, y + height],
|
|
73
|
+
],
|
|
74
|
+
borderOptions,
|
|
75
|
+
);
|
|
76
|
+
}
|
|
77
|
+
// Draw horizontals; the last row line is the rectangle's bottom edge.
|
|
78
|
+
for (var index = 0; index < rowLines.length - 1; index++) {
|
|
79
|
+
var yPos = rowLines[index];
|
|
80
|
+
self.line(
|
|
81
|
+
[
|
|
82
|
+
[x, yPos],
|
|
83
|
+
[x + width, yPos],
|
|
84
|
+
],
|
|
85
|
+
borderOptions,
|
|
86
|
+
);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
44
89
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
90
|
+
/**
|
|
91
|
+
* Resolves the table's data fields: `order` when given, otherwise the names
|
|
92
|
+
* of the configured `columns`, otherwise every field found in any record, in
|
|
93
|
+
* first-seen order.
|
|
94
|
+
* @private
|
|
95
|
+
*/
|
|
96
|
+
function tableFields(contents, options) {
|
|
97
|
+
if (options.order && options.order.length) {
|
|
98
|
+
return typeof options.order === "string"
|
|
99
|
+
? options.order
|
|
100
|
+
.split(",")
|
|
101
|
+
.map((field) => field.trim())
|
|
102
|
+
.filter(Boolean)
|
|
103
|
+
: options.order.slice();
|
|
104
|
+
}
|
|
105
|
+
if (options.columns && options.columns.length) {
|
|
106
|
+
return options.columns.map((column) => column.name);
|
|
107
|
+
}
|
|
108
|
+
var fields = [];
|
|
109
|
+
for (var record of contents) {
|
|
110
|
+
for (var field of Object.keys(record || {})) {
|
|
111
|
+
if (!fields.includes(field)) {
|
|
112
|
+
fields.push(field);
|
|
113
|
+
}
|
|
69
114
|
}
|
|
70
115
|
}
|
|
116
|
+
return fields;
|
|
71
117
|
}
|
|
72
118
|
|
|
73
119
|
/**
|
|
74
120
|
* Display text data in tabular form
|
|
121
|
+
* Rows and headers use their rendered text-box heights, including padding,
|
|
122
|
+
* minimum heights, fixed heights, and HTML layout. Empty contents or no selected
|
|
123
|
+
* columns leave the Recipe unchanged. Array-form order preserves exact keys.
|
|
124
|
+
* Header text styles are independent of body styles: column header options
|
|
125
|
+
* (or defaults) are overridden by table header options, then alignToData
|
|
126
|
+
* and column hcell box overrides are applied.
|
|
75
127
|
* @name table
|
|
76
128
|
* @function
|
|
77
129
|
* @memberof Recipe#
|
|
@@ -108,6 +160,7 @@ function drawTableBorder(self, x, y, width, height, rowLines, options) {
|
|
|
108
160
|
* @param {function} [options.overflow] - Called when the next table entry is going to expand the table
|
|
109
161
|
* beyond the given height or page boundary. Its parameters are (self, row) where 'self' is the recipe handle so
|
|
110
162
|
* that other recipe interfaces can be called, and the row number of the data which caused the data overflow.
|
|
163
|
+
* The callback's `this` is also the Recipe instance.
|
|
111
164
|
* The return value can be 'true' which indicates that data processing should stop, or 'false' which indicates that
|
|
112
165
|
* the data should continue being processed with the original [x,y] coordinates, or it can be an object containing
|
|
113
166
|
* a 'position' property indicating the [x,y] coordinates where the next table for the remaining data should start.
|
|
@@ -116,88 +169,80 @@ function drawTableBorder(self, x, y, width, height, rowLines, options) {
|
|
|
116
169
|
* @param {string} [options.row.nth] - 'even|odd', indicating that the properties should be applied only to
|
|
117
170
|
* 'even' or 'odd' rows.
|
|
118
171
|
* @returns {Recipe} The recipe instance.
|
|
172
|
+
* @throws {RangeError} If the overflow callback continues into an area too small
|
|
173
|
+
* for the pending row and its repeated header. Return true to stop, or provide
|
|
174
|
+
* enough space; rows are not split and the callback is called once per overflow.
|
|
175
|
+
* @throws {Error} If the overflow callback continues after ending the page
|
|
176
|
+
* without starting another one.
|
|
119
177
|
*/
|
|
120
178
|
exports.table = function table(x, y, contents, options = {}) {
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
let order = options.order || [];
|
|
124
|
-
let columns = [];
|
|
125
|
-
|
|
126
|
-
if (order.length !== 0) {
|
|
127
|
-
if (typeof options.order === "string") {
|
|
128
|
-
order = options.order.split(",");
|
|
129
|
-
}
|
|
130
|
-
} else {
|
|
131
|
-
if (!options.columns || options.columns.length > fields.length) {
|
|
132
|
-
order = fields; // all fields emitted, columns in order of first record
|
|
133
|
-
} else {
|
|
134
|
-
// columns in order found in options
|
|
135
|
-
for (const column of options.columns) {
|
|
136
|
-
order.push(column.name);
|
|
137
|
-
}
|
|
138
|
-
}
|
|
179
|
+
if (!Array.isArray(contents) || contents.length === 0) {
|
|
180
|
+
return this;
|
|
139
181
|
}
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
found = true;
|
|
149
|
-
break;
|
|
150
|
-
}
|
|
151
|
-
}
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
if (!found) {
|
|
155
|
-
columns.push({ text: field, name: field });
|
|
156
|
-
}
|
|
157
|
-
}
|
|
182
|
+
var columns = tableFields(contents, options).map((field) => {
|
|
183
|
+
var column =
|
|
184
|
+
options.columns &&
|
|
185
|
+
options.columns.find((definition) => definition.name === field);
|
|
186
|
+
return column || { text: field, name: field };
|
|
187
|
+
});
|
|
188
|
+
if (columns.length === 0) {
|
|
189
|
+
return this;
|
|
158
190
|
}
|
|
159
191
|
this.layout("_table_", x, y, 0, 0, { columns: columns, reset: true });
|
|
160
192
|
|
|
161
|
-
|
|
193
|
+
var tableWidth = this._layouts["_table_"].reduce((width, column) => {
|
|
162
194
|
width += column.width;
|
|
163
195
|
return width;
|
|
164
196
|
}, 0);
|
|
165
197
|
|
|
166
|
-
let tableHeight = 0;
|
|
167
|
-
let headerHeight = 0;
|
|
168
|
-
let rowLines = [];
|
|
169
|
-
let currentY = y;
|
|
170
198
|
this._previousTextObjects = [];
|
|
171
|
-
|
|
172
|
-
|
|
199
|
+
var nth;
|
|
200
|
+
var rowOptions = {};
|
|
201
|
+
|
|
202
|
+
/** Resolves header styles identically for measurement and drawing. */
|
|
203
|
+
var headerOptions = (column) => {
|
|
204
|
+
var colOptions = clone(column.options.header);
|
|
205
|
+
if (typeof options.header === "object") {
|
|
206
|
+
colOptions = this._merge(colOptions, getCellOptions(options.header));
|
|
207
|
+
}
|
|
208
|
+
// Have header alignment match data alignment?
|
|
209
|
+
if (options.header.alignToData && column.options.textBox.textAlign) {
|
|
210
|
+
colOptions.textBox.textAlign = column.options.textBox.textAlign;
|
|
211
|
+
}
|
|
212
|
+
// Is there a specific header cell override in this column?
|
|
213
|
+
if (column.options.hcell) {
|
|
214
|
+
var cellOptions = getCellOptions(column.options, "hcell");
|
|
215
|
+
colOptions.textBox = this._merge(
|
|
216
|
+
colOptions.textBox,
|
|
217
|
+
clone(cellOptions.textBox),
|
|
218
|
+
);
|
|
219
|
+
}
|
|
220
|
+
return colOptions;
|
|
221
|
+
};
|
|
173
222
|
|
|
223
|
+
var headerHeight = 0;
|
|
174
224
|
if (options.header) {
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
const cellHeight = getCellHeight(this, column.text, column, colOptions);
|
|
225
|
+
for (var column of this._layouts["_table_"]) {
|
|
226
|
+
var cellHeight = getCellHeight(
|
|
227
|
+
this,
|
|
228
|
+
column.text,
|
|
229
|
+
column,
|
|
230
|
+
headerOptions(column),
|
|
231
|
+
);
|
|
184
232
|
headerHeight = Math.max(headerHeight, cellHeight);
|
|
185
233
|
}
|
|
186
234
|
}
|
|
187
235
|
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
236
|
+
/** Recomputes bounds for each continuation position and page. */
|
|
237
|
+
var segmentBottom = (top) => {
|
|
238
|
+
var bottom = options.height ? top + options.height : 0;
|
|
239
|
+
var pageBottom =
|
|
192
240
|
this.pageInfo(this.pageNumber).height - this._margin.bottom;
|
|
193
|
-
if (
|
|
194
|
-
|
|
241
|
+
if (bottom === 0 || bottom > pageBottom) {
|
|
242
|
+
bottom = pageBottom;
|
|
195
243
|
}
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
if (options.border) {
|
|
199
|
-
options.border.lineCap = "butt"; // keep borders from extending outside of enclosing box.
|
|
200
|
-
}
|
|
244
|
+
return bottom;
|
|
245
|
+
};
|
|
201
246
|
|
|
202
247
|
if (options.row) {
|
|
203
248
|
rowOptions = getCellOptions(options.row);
|
|
@@ -221,46 +266,78 @@ exports.table = function table(x, y, contents, options = {}) {
|
|
|
221
266
|
}
|
|
222
267
|
}
|
|
223
268
|
|
|
224
|
-
|
|
225
|
-
|
|
269
|
+
var tableBottom = options.overflow ? segmentBottom(y) : 0;
|
|
270
|
+
var tableHeight = 0;
|
|
271
|
+
var rowLines = [];
|
|
272
|
+
var currentY = y;
|
|
273
|
+
var firstTime = true;
|
|
274
|
+
var row = 0;
|
|
226
275
|
|
|
227
|
-
for (
|
|
228
|
-
let rowHeight = 0;
|
|
276
|
+
for (var record of contents) {
|
|
229
277
|
row++;
|
|
230
278
|
|
|
231
|
-
//
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
279
|
+
// Resolve every cell once: the renderer runs once per cell, and its
|
|
280
|
+
// options size the row as well as style the drawn text.
|
|
281
|
+
var cells = this._layouts["_table_"].map((column) => {
|
|
282
|
+
var field = column.field;
|
|
283
|
+
var value = Object.prototype.hasOwnProperty.call(record, field)
|
|
284
|
+
? record[field]
|
|
285
|
+
: undefined;
|
|
286
|
+
var text = value === undefined || value === null ? "" : value;
|
|
287
|
+
var colOptions = clone(options);
|
|
288
|
+
// The table callback is not a text-flow overflow callback.
|
|
289
|
+
delete colOptions.overflow;
|
|
290
|
+
colOptions = this._merge(colOptions, clone(column.options));
|
|
291
|
+
if (nth && nth(row)) {
|
|
292
|
+
colOptions = this._merge(colOptions, clone(rowOptions));
|
|
293
|
+
}
|
|
294
|
+
if (column.options.renderer) {
|
|
295
|
+
var renderOptions = column.options.renderer(text, record, field, row);
|
|
296
|
+
if (renderOptions) {
|
|
297
|
+
colOptions = this._merge(colOptions, renderOptions);
|
|
240
298
|
}
|
|
241
|
-
const cellHeight = getCellHeight(this, text, column, colOptions);
|
|
242
|
-
rowHeight = Math.max(rowHeight, cellHeight);
|
|
243
299
|
}
|
|
300
|
+
return { column, text: String(text), options: colOptions };
|
|
301
|
+
});
|
|
302
|
+
|
|
303
|
+
var rowHeight = 0;
|
|
304
|
+
for (var cell of cells) {
|
|
305
|
+
var cellHeight = getCellHeight(
|
|
306
|
+
this,
|
|
307
|
+
cell.text,
|
|
308
|
+
cell.column,
|
|
309
|
+
cell.options,
|
|
310
|
+
);
|
|
311
|
+
rowHeight = Math.max(rowHeight, cellHeight);
|
|
244
312
|
}
|
|
245
313
|
|
|
246
314
|
// When table gets 'full', let user know when overflow callback provided.
|
|
247
315
|
// They can choose to bail out of table filling loop, or keep on going with
|
|
248
316
|
// appropriate variables reset to initial values. This gives the user the
|
|
249
317
|
// opportunity to change to a new page to continue table production with
|
|
250
|
-
// remaining rows of data.
|
|
251
|
-
|
|
318
|
+
// remaining rows of data. A continuation reserves room for its repeated
|
|
319
|
+
// header as well as the row.
|
|
320
|
+
var needed = rowHeight + (firstTime && options.header ? headerHeight : 0);
|
|
321
|
+
if (options.overflow && currentY + needed > tableBottom) {
|
|
252
322
|
drawTableBorder(this, x, y, tableWidth, tableHeight, rowLines, options);
|
|
253
323
|
|
|
254
|
-
|
|
324
|
+
var orders = options.overflow.call(this, this, row);
|
|
255
325
|
|
|
256
326
|
if (orders === true) {
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
327
|
+
// stop processing table data
|
|
328
|
+
tableHeight = 0;
|
|
329
|
+
break;
|
|
330
|
+
}
|
|
331
|
+
if (!this.page) {
|
|
332
|
+
throw new Error(
|
|
333
|
+
"Recipe.table: the overflow callback must leave an active page to continue on.",
|
|
334
|
+
);
|
|
335
|
+
}
|
|
336
|
+
if (orders && orders.position) {
|
|
260
337
|
[x, y] = orders.position;
|
|
261
|
-
|
|
338
|
+
var xx = x;
|
|
262
339
|
// Make sure x position adjusted in all columns
|
|
263
|
-
for (
|
|
340
|
+
for (var column of this._layouts["_table_"]) {
|
|
264
341
|
column.x = xx;
|
|
265
342
|
xx += column.width;
|
|
266
343
|
}
|
|
@@ -270,32 +347,18 @@ exports.table = function table(x, y, contents, options = {}) {
|
|
|
270
347
|
currentY = y;
|
|
271
348
|
tableHeight = 0;
|
|
272
349
|
rowLines = [];
|
|
350
|
+
tableBottom = segmentBottom(y);
|
|
351
|
+
if (currentY + rowHeight + headerHeight > tableBottom) {
|
|
352
|
+
throw new RangeError(
|
|
353
|
+
`Recipe.table: row ${row} and its header do not fit in the continuation area.`,
|
|
354
|
+
);
|
|
355
|
+
}
|
|
273
356
|
}
|
|
274
357
|
|
|
275
358
|
if (firstTime && options.header) {
|
|
276
359
|
// Display table header
|
|
277
|
-
for (
|
|
278
|
-
|
|
279
|
-
if (typeof options.header === "object") {
|
|
280
|
-
const cellOptions = getCellOptions(options.header);
|
|
281
|
-
colOptions = this._merge(colOptions, clone(cellOptions));
|
|
282
|
-
}
|
|
283
|
-
|
|
284
|
-
// Have header alignment match data alignment?
|
|
285
|
-
if (options.header.alignToData && column.options.textBox.textAlign) {
|
|
286
|
-
colOptions.textBox.textAlign = column.options.textBox.textAlign;
|
|
287
|
-
}
|
|
288
|
-
|
|
289
|
-
// Is there a specific header cell override in this column?
|
|
290
|
-
if (column.options.hcell) {
|
|
291
|
-
const cellOptions = getCellOptions(column.options, "hcell");
|
|
292
|
-
colOptions.textBox = this._merge(
|
|
293
|
-
colOptions.textBox,
|
|
294
|
-
clone(cellOptions.textBox),
|
|
295
|
-
);
|
|
296
|
-
}
|
|
297
|
-
|
|
298
|
-
colOptions = this._merge(colOptions, {
|
|
360
|
+
for (var column of this._layouts["_table_"]) {
|
|
361
|
+
var colOptions = this._merge(headerOptions(column), {
|
|
299
362
|
textBox: { minHeight: headerHeight, width: column.width },
|
|
300
363
|
});
|
|
301
364
|
this.text(column.text, column.x, currentY, colOptions);
|
|
@@ -309,27 +372,11 @@ exports.table = function table(x, y, contents, options = {}) {
|
|
|
309
372
|
firstTime = false;
|
|
310
373
|
|
|
311
374
|
// Now write out table cells for current record
|
|
312
|
-
for (
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
if (text === undefined) {
|
|
316
|
-
text = "";
|
|
317
|
-
}
|
|
318
|
-
let colOptions = clone(options);
|
|
319
|
-
colOptions = this._merge(colOptions, clone(column.options));
|
|
320
|
-
if (nth && nth(row)) {
|
|
321
|
-
colOptions = this._merge(colOptions, clone(rowOptions));
|
|
322
|
-
}
|
|
323
|
-
if (column.options.renderer) {
|
|
324
|
-
let renderOptions = column.options.renderer(text, record, field, row);
|
|
325
|
-
if (renderOptions) {
|
|
326
|
-
colOptions = this._merge(colOptions, renderOptions);
|
|
327
|
-
}
|
|
328
|
-
}
|
|
329
|
-
colOptions = this._merge(colOptions, {
|
|
330
|
-
textBox: { minHeight: rowHeight, width: column.width },
|
|
375
|
+
for (var cell of cells) {
|
|
376
|
+
var colOptions = this._merge(cell.options, {
|
|
377
|
+
textBox: { minHeight: rowHeight, width: cell.column.width },
|
|
331
378
|
});
|
|
332
|
-
this.text(text, column.x, currentY, colOptions);
|
|
379
|
+
this.text(cell.text, cell.column.x, currentY, colOptions);
|
|
333
380
|
}
|
|
334
381
|
|
|
335
382
|
currentY += rowHeight;
|
|
@@ -339,5 +386,12 @@ exports.table = function table(x, y, contents, options = {}) {
|
|
|
339
386
|
|
|
340
387
|
drawTableBorder(this, x, y, tableWidth, tableHeight, rowLines, options);
|
|
341
388
|
|
|
389
|
+
// Leave the text cursor at the table's left edge, below its last segment.
|
|
390
|
+
this.x = x;
|
|
391
|
+
this.y = currentY;
|
|
392
|
+
this.box = { x, y: currentY };
|
|
393
|
+
this._flow = false;
|
|
394
|
+
this._previousTextObjects = [];
|
|
395
|
+
|
|
342
396
|
return this;
|
|
343
397
|
};
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
var { cloneOptions, resolveFontSize } = require("./utils");
|
|
2
|
+
|
|
1
3
|
const charSpacing = function charSpacing(text, charSpace) {
|
|
2
4
|
let txt = text.replace(/^(?:(?!\u00a0)\s)+|(?:(?!\u00a0)\s)+$/g, "");
|
|
3
5
|
return txt.length ? (txt.length - 1) * charSpace : 0;
|
|
@@ -246,7 +248,7 @@ exports.textDimensions = function textDimensions(text, options = {}) {
|
|
|
246
248
|
if (options.charSpace) {
|
|
247
249
|
charSpaces = charSpacing(text, options.charSpace);
|
|
248
250
|
}
|
|
249
|
-
const fontSize = options
|
|
251
|
+
const fontSize = resolveFontSize(options, this.current.defaultFontSize);
|
|
250
252
|
dimensions = font.calculateTextDimensions(text, fontSize);
|
|
251
253
|
dimensions.xMax += charSpaces;
|
|
252
254
|
}
|
|
@@ -276,7 +278,7 @@ exports.Column = class Column {
|
|
|
276
278
|
this._field = field; // associated data field
|
|
277
279
|
this._text = text || field; // for column title
|
|
278
280
|
this._gap = 0;
|
|
279
|
-
this._options =
|
|
281
|
+
this._options = cloneOptions(options);
|
|
280
282
|
|
|
281
283
|
this._options.textBox = this._options.cell;
|
|
282
284
|
|