@muhammara/native-core 7.0.0-beta.4 → 7.0.0-rc.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/README.md +57 -7
- package/THIRD_PARTY_NOTICES.md +39 -0
- package/index.js +120 -1
- package/lib/PDFRStreamForBuffer.js +52 -7
- package/lib/PDFRStreamForFile.js +56 -7
- package/lib/PDFStreamForResponse.js +22 -5
- package/lib/PDFWStreamForBuffer.js +49 -10
- package/lib/PDFWStreamForFile.js +26 -5
- package/lib/Recipe.js +91 -38
- package/lib/content-stream.js +503 -0
- package/lib/css-colors.js +149 -0
- package/lib/font-text.js +1461 -0
- package/lib/glyph-list.js +1127 -0
- package/lib/recipe/annotation.js +464 -101
- package/lib/recipe/appendPage.js +2 -0
- package/lib/recipe/colors.js +132 -35
- package/lib/recipe/coordinate.js +82 -16
- package/lib/recipe/encrypt.js +32 -13
- package/lib/recipe/font.js +70 -25
- package/lib/recipe/graphics-state.js +3 -2
- package/lib/recipe/htmlToTextObjects.js +121 -24
- package/lib/recipe/image.js +385 -39
- package/lib/recipe/info.js +93 -22
- package/lib/recipe/insertPage.js +12 -3
- package/lib/recipe/overlay.js +4 -2
- package/lib/recipe/page-references.js +436 -0
- package/lib/recipe/page.js +363 -262
- package/lib/recipe/parameters.js +8 -1
- package/lib/recipe/replaceText.js +464 -30
- package/lib/recipe/shapes.js +418 -45
- package/lib/recipe/split.js +6 -2
- package/lib/recipe/table.js +41 -8
- package/lib/recipe/text.helper.js +172 -8
- package/lib/recipe/text.js +294 -56
- package/lib/recipe/utils.js +17 -6
- package/lib/recipe/vector-line.js +101 -39
- package/lib/recipe/vector-polygon.js +18 -6
- package/lib/recipe/vector.helper.js +156 -14
- package/lib/recipe/vector.js +156 -52
- package/lib/recipe/xObjectForm.js +73 -10
- package/lib/recipe-constants.js +373 -0
- package/lib/recipe-options.js +47 -0
- package/muhammara.d.ts +3501 -160
- package/package.json +2 -3
package/lib/recipe/split.js
CHANGED
|
@@ -8,8 +8,12 @@ const utils = require("./utils");
|
|
|
8
8
|
* @function
|
|
9
9
|
* @memberof Recipe#
|
|
10
10
|
* @param {string} [outputDir=''] - The path for the output PDFs.
|
|
11
|
-
* @param {string} [prefix] - The output filename prefix. Defaults to the
|
|
12
|
-
*
|
|
11
|
+
* @param {string} [prefix] - The output filename prefix. Defaults to the
|
|
12
|
+
* source filename; pass one for a Buffer source, which has no filename.
|
|
13
|
+
* @returns {Recipe} The recipe instance. Each page is written to
|
|
14
|
+
* `<outputDir>/<prefix>-<pageNumber>.pdf`.
|
|
15
|
+
* @throws {Error} If the source reader was released by endPDF(), or an output
|
|
16
|
+
* file cannot be written.
|
|
13
17
|
*/
|
|
14
18
|
exports.split = function split(outputDir = "", prefix) {
|
|
15
19
|
prefix = prefix || this.filename;
|
package/lib/recipe/table.js
CHANGED
|
@@ -1,7 +1,15 @@
|
|
|
1
1
|
var { htmlToTextObjects } = require("./htmlToTextObjects");
|
|
2
2
|
var { cloneOptions: clone } = require("./utils");
|
|
3
|
+
var { LineCap, TableRowNth } = require("../recipe-constants");
|
|
3
4
|
|
|
4
|
-
/**
|
|
5
|
+
/**
|
|
6
|
+
* Convert a table cell style into text options: a copy of the options with
|
|
7
|
+
* the cell entry moved to `textBox`.
|
|
8
|
+
* @private
|
|
9
|
+
* @param {Object} options - The table, header, row or column options.
|
|
10
|
+
* @param {string} [cell='cell'] - The key holding the cell style, "cell" or "hcell".
|
|
11
|
+
* @returns {Object} The text options.
|
|
12
|
+
*/
|
|
5
13
|
function getCellOptions(options, cell = "cell") {
|
|
6
14
|
var cellOptions = clone(options);
|
|
7
15
|
|
|
@@ -13,7 +21,16 @@ function getCellOptions(options, cell = "cell") {
|
|
|
13
21
|
return cellOptions;
|
|
14
22
|
}
|
|
15
23
|
|
|
16
|
-
/**
|
|
24
|
+
/**
|
|
25
|
+
* Measure the outer box height text() will draw for a cell.
|
|
26
|
+
* @private
|
|
27
|
+
* @param {Recipe} self - The recipe instance.
|
|
28
|
+
* @param {string} text - The cell text or HTML.
|
|
29
|
+
* @param {Object} column - The table layout column: x, y and width.
|
|
30
|
+
* @param {Object} options - The cell text options.
|
|
31
|
+
* @returns {number} The box height, including padding and minimum height.
|
|
32
|
+
* @throws {TypeError} If no page is active.
|
|
33
|
+
*/
|
|
17
34
|
function getCellHeight(self, text, column, options) {
|
|
18
35
|
var colOptions = self._merge(options, { textBox: { width: column.width } });
|
|
19
36
|
var originCoord = self._calibrateCoordinate(
|
|
@@ -44,7 +61,19 @@ function getCellHeight(self, text, column, options) {
|
|
|
44
61
|
);
|
|
45
62
|
}
|
|
46
63
|
|
|
47
|
-
/**
|
|
64
|
+
/**
|
|
65
|
+
* Draw the border of a completed table segment without duplicating its
|
|
66
|
+
* bottom edge.
|
|
67
|
+
* @private
|
|
68
|
+
* @param {Recipe} self - The recipe instance.
|
|
69
|
+
* @param {number} x - The segment left.
|
|
70
|
+
* @param {number} y - The segment top.
|
|
71
|
+
* @param {number} width - The segment width.
|
|
72
|
+
* @param {number} height - The segment height; nothing is drawn when 0.
|
|
73
|
+
* @param {number[]} rowLines - The y of every row bottom.
|
|
74
|
+
* @param {Object} options - The table options; `border` enables drawing.
|
|
75
|
+
* @returns {void}
|
|
76
|
+
*/
|
|
48
77
|
function drawTableBorder(self, x, y, width, height, rowLines, options) {
|
|
49
78
|
// A segment without rows has nothing to enclose.
|
|
50
79
|
if (!options.border || height <= 0) {
|
|
@@ -54,7 +83,7 @@ function drawTableBorder(self, x, y, width, height, rowLines, options) {
|
|
|
54
83
|
{},
|
|
55
84
|
options.border === true ? {} : options.border,
|
|
56
85
|
// Keep borders from extending outside of the enclosing box.
|
|
57
|
-
{ lineCap:
|
|
86
|
+
{ lineCap: LineCap.BUTT },
|
|
58
87
|
);
|
|
59
88
|
if (!borderOptions.width) {
|
|
60
89
|
borderOptions.width = 0.5;
|
|
@@ -92,6 +121,9 @@ function drawTableBorder(self, x, y, width, height, rowLines, options) {
|
|
|
92
121
|
* of the configured `columns`, otherwise every field found in any record, in
|
|
93
122
|
* first-seen order.
|
|
94
123
|
* @private
|
|
124
|
+
* @param {Object[]} contents - The table records.
|
|
125
|
+
* @param {Object} options - The table options.
|
|
126
|
+
* @returns {string[]} The field names, in column order.
|
|
95
127
|
*/
|
|
96
128
|
function tableFields(contents, options) {
|
|
97
129
|
if (options.order && options.order.length) {
|
|
@@ -166,9 +198,10 @@ function tableFields(contents, options) {
|
|
|
166
198
|
* a 'position' property indicating the [x,y] coordinates where the next table for the remaining data should start.
|
|
167
199
|
* @param {object} [options.row] - text properties to be applied to all cells in a table row.
|
|
168
200
|
* @param {object} [options.row.cell] - All textBox options from the 'text' interface can be used here.
|
|
169
|
-
* @param {
|
|
170
|
-
* 'even' or 'odd' rows.
|
|
201
|
+
* @param {Recipe.TableRowNth} [options.row.nth] - A `Recipe.TableRowNth` value, indicating that the
|
|
202
|
+
* properties should be applied only to 'even' or 'odd' rows.
|
|
171
203
|
* @returns {Recipe} The recipe instance.
|
|
204
|
+
* @throws {TypeError} If no page is active.
|
|
172
205
|
* @throws {RangeError} If the overflow callback continues into an area too small
|
|
173
206
|
* for the pending row and its repeated header. Return true to stop, or provide
|
|
174
207
|
* enough space; rows are not split and the callback is called once per overflow.
|
|
@@ -248,12 +281,12 @@ exports.table = function table(x, y, contents, options = {}) {
|
|
|
248
281
|
rowOptions = getCellOptions(options.row);
|
|
249
282
|
|
|
250
283
|
switch (options.row.nth) {
|
|
251
|
-
case
|
|
284
|
+
case TableRowNth.EVEN:
|
|
252
285
|
nth = (row) => {
|
|
253
286
|
return row % 2 === 0;
|
|
254
287
|
};
|
|
255
288
|
break;
|
|
256
|
-
case
|
|
289
|
+
case TableRowNth.ODD:
|
|
257
290
|
nth = (row) => {
|
|
258
291
|
return row % 2 !== 0;
|
|
259
292
|
};
|
|
@@ -1,13 +1,29 @@
|
|
|
1
1
|
var { cloneOptions, resolveFontSize } = require("./utils");
|
|
2
|
+
var { HorizontalAlign, VerticalAlign } = require("../recipe-constants");
|
|
2
3
|
|
|
4
|
+
/**
|
|
5
|
+
* The width character spacing adds between the characters of a text.
|
|
6
|
+
* @private
|
|
7
|
+
* @param {string} text - The text.
|
|
8
|
+
* @param {number} charSpace - The spacing added after each character but the last.
|
|
9
|
+
* @returns {number} The added width.
|
|
10
|
+
*/
|
|
3
11
|
const charSpacing = function charSpacing(text, charSpace) {
|
|
4
|
-
|
|
5
|
-
return
|
|
12
|
+
var characterCount = Array.from(String(text)).length;
|
|
13
|
+
return characterCount ? (characterCount - 1) * charSpace : 0;
|
|
6
14
|
};
|
|
7
15
|
|
|
8
16
|
// Have to set up word as a constant, then export it below
|
|
9
17
|
// so that Line can see it. Otherwise, an error is thrown.
|
|
10
18
|
|
|
19
|
+
/**
|
|
20
|
+
* A word used by Recipe text layout.
|
|
21
|
+
* @name Word
|
|
22
|
+
* @class
|
|
23
|
+
* @memberof Recipe#
|
|
24
|
+
* @param {string} word - The word, a single space measured as "o".
|
|
25
|
+
* @param {Object} pathOptions - The resolved text options: font, size and charSpace.
|
|
26
|
+
*/
|
|
11
27
|
const Word = class Word {
|
|
12
28
|
constructor(word, pathOptions) {
|
|
13
29
|
this._value = word;
|
|
@@ -16,10 +32,17 @@ const Word = class Word {
|
|
|
16
32
|
this._text = word === " " ? "o" : word; // allows space to get an actual dimension
|
|
17
33
|
}
|
|
18
34
|
|
|
35
|
+
/**
|
|
36
|
+
* @returns {string} The word text.
|
|
37
|
+
*/
|
|
19
38
|
get value() {
|
|
20
39
|
return this._value;
|
|
21
40
|
}
|
|
22
41
|
|
|
42
|
+
/**
|
|
43
|
+
* The measured text box, including character spacing; cached.
|
|
44
|
+
* @returns {Object} xMin, yMin, xMax, yMax, width and height.
|
|
45
|
+
*/
|
|
23
46
|
get dimensions() {
|
|
24
47
|
if (this._dimensions) {
|
|
25
48
|
return this._dimensions;
|
|
@@ -32,14 +55,26 @@ const Word = class Word {
|
|
|
32
55
|
return this._dimensions;
|
|
33
56
|
}
|
|
34
57
|
|
|
58
|
+
/**
|
|
59
|
+
* @returns {boolean} Whether this is the last word of its line.
|
|
60
|
+
*/
|
|
35
61
|
get last() {
|
|
36
62
|
return this._last;
|
|
37
63
|
}
|
|
38
64
|
|
|
65
|
+
/**
|
|
66
|
+
* @returns {number} The width character spacing adds to the word.
|
|
67
|
+
*/
|
|
39
68
|
get charSpacing() {
|
|
40
69
|
return charSpacing(this._text, this._pathOptions.charSpace);
|
|
41
70
|
}
|
|
42
71
|
|
|
72
|
+
/**
|
|
73
|
+
* Mark the word as the last of its line, trimming trailing space and
|
|
74
|
+
* measuring it again.
|
|
75
|
+
* @param {boolean} [value=true] - Whether the word is last.
|
|
76
|
+
* @returns {void}
|
|
77
|
+
*/
|
|
43
78
|
lastWord(value = true) {
|
|
44
79
|
// indicate last word in line (for justification)
|
|
45
80
|
this._last = value;
|
|
@@ -75,9 +110,19 @@ exports.Word = Word; // ... now export Word to the rest of the library.
|
|
|
75
110
|
* @param {number} size - The font size.
|
|
76
111
|
* @param {Object} pathOptions - The resolved text options.
|
|
77
112
|
*/
|
|
113
|
+
// The width of a line without a text box. No text reaches it, so such a line
|
|
114
|
+
// accepts every word without measuring.
|
|
115
|
+
const UNBOUNDED_LINE_WIDTH = 999999999;
|
|
116
|
+
|
|
78
117
|
exports.Line = class Line {
|
|
118
|
+
/**
|
|
119
|
+
* @param {number} [width] - The available width; unlimited when omitted.
|
|
120
|
+
* @param {number} [height] - A fixed line height.
|
|
121
|
+
* @param {number} [size] - The font size; defaults to the text options size.
|
|
122
|
+
* @param {Object} pathOptions - The resolved text options.
|
|
123
|
+
*/
|
|
79
124
|
constructor(width, height, size, pathOptions) {
|
|
80
|
-
this._width = width ||
|
|
125
|
+
this._width = width || UNBOUNDED_LINE_WIDTH;
|
|
81
126
|
this._height = height;
|
|
82
127
|
this._pathOptions = pathOptions;
|
|
83
128
|
this.size = size || pathOptions.size;
|
|
@@ -85,41 +130,75 @@ exports.Line = class Line {
|
|
|
85
130
|
this.wordObjects = [];
|
|
86
131
|
}
|
|
87
132
|
|
|
133
|
+
/**
|
|
134
|
+
* Replace the line ID; falsy values are ignored.
|
|
135
|
+
* @param {number} id - The new ID.
|
|
136
|
+
*/
|
|
88
137
|
set lineID(id) {
|
|
89
138
|
if (id) {
|
|
90
139
|
this._lineID = id;
|
|
91
140
|
}
|
|
92
141
|
}
|
|
93
142
|
|
|
143
|
+
/**
|
|
144
|
+
* @returns {number} The line ID, grouping objects laid out on one line.
|
|
145
|
+
*/
|
|
94
146
|
get lineID() {
|
|
95
147
|
return this._lineID;
|
|
96
148
|
}
|
|
97
149
|
|
|
150
|
+
/**
|
|
151
|
+
* @param {Word} wordObject - The word to append.
|
|
152
|
+
* @returns {void}
|
|
153
|
+
*/
|
|
98
154
|
addWord(wordObject) {
|
|
99
155
|
this.wordObjects.push(wordObject);
|
|
100
156
|
}
|
|
101
157
|
|
|
158
|
+
/**
|
|
159
|
+
* Append leading spaces.
|
|
160
|
+
* @param {number} amount - The number of spaces.
|
|
161
|
+
* @returns {void}
|
|
162
|
+
*/
|
|
102
163
|
indent(amount) {
|
|
103
164
|
for (let i = 0; i < amount; i++) {
|
|
104
165
|
this.addWord(new Word(" ", this._pathOptions));
|
|
105
166
|
}
|
|
106
167
|
}
|
|
107
168
|
|
|
169
|
+
/**
|
|
170
|
+
* Mark the final word as the last of the line.
|
|
171
|
+
* @returns {void}
|
|
172
|
+
*/
|
|
108
173
|
markLastWord() {
|
|
109
174
|
if (this.wordObjects.length > 0) {
|
|
110
175
|
this.wordObjects[this.wordObjects.length - 1].lastWord();
|
|
111
176
|
}
|
|
112
177
|
}
|
|
113
178
|
|
|
179
|
+
/**
|
|
180
|
+
* @returns {Word|undefined} The final word, or undefined for an empty line.
|
|
181
|
+
*/
|
|
114
182
|
get lastWord() {
|
|
115
183
|
return this.wordObjects[this.wordObjects.length - 1];
|
|
116
184
|
}
|
|
117
185
|
|
|
186
|
+
/**
|
|
187
|
+
* @param {string} text - The text.
|
|
188
|
+
* @returns {number} The width character spacing adds to the text.
|
|
189
|
+
*/
|
|
118
190
|
charSpacing(text) {
|
|
119
191
|
return charSpacing(text, this._pathOptions.charSpace);
|
|
120
192
|
}
|
|
121
193
|
|
|
194
|
+
/**
|
|
195
|
+
* @param {Word} wordObject - The word to test.
|
|
196
|
+
* @returns {boolean} Whether the line still fits its width with the word appended.
|
|
197
|
+
*/
|
|
122
198
|
canFit(wordObject) {
|
|
199
|
+
// Measuring the whole line for every word is quadratic in its length, and
|
|
200
|
+
// a line without a text box never wraps.
|
|
201
|
+
if (this._width >= UNBOUNDED_LINE_WIDTH) return true;
|
|
123
202
|
const tempValue = this.value + wordObject.value;
|
|
124
203
|
const toWidth =
|
|
125
204
|
this._pathOptions.font.calculateTextDimensions(tempValue, this.size)
|
|
@@ -127,6 +206,11 @@ exports.Line = class Line {
|
|
|
127
206
|
return toWidth <= this.width;
|
|
128
207
|
}
|
|
129
208
|
|
|
209
|
+
/**
|
|
210
|
+
* Replace the final word and mark the new one as last.
|
|
211
|
+
* @param {Word|string} wordObject - The replacement word.
|
|
212
|
+
* @returns {void}
|
|
213
|
+
*/
|
|
130
214
|
replaceLastWord(wordObject) {
|
|
131
215
|
if (typeof wordObject === "string") {
|
|
132
216
|
wordObject = new Word(wordObject, this._pathOptions);
|
|
@@ -136,14 +220,23 @@ exports.Line = class Line {
|
|
|
136
220
|
wordObject.lastWord();
|
|
137
221
|
}
|
|
138
222
|
|
|
223
|
+
/**
|
|
224
|
+
* @returns {Word[]} The words of the line.
|
|
225
|
+
*/
|
|
139
226
|
get words() {
|
|
140
227
|
return this.wordObjects;
|
|
141
228
|
}
|
|
142
229
|
|
|
230
|
+
/**
|
|
231
|
+
* @returns {number} The width of one space, measured as "o".
|
|
232
|
+
*/
|
|
143
233
|
get spaceWidth() {
|
|
144
234
|
return this._pathOptions.font.calculateTextDimensions("o", this.size).width;
|
|
145
235
|
}
|
|
146
236
|
|
|
237
|
+
/**
|
|
238
|
+
* @returns {string} The text of the line.
|
|
239
|
+
*/
|
|
147
240
|
get value() {
|
|
148
241
|
const value = this.wordObjects.reduce((string, word) => {
|
|
149
242
|
string += word.value;
|
|
@@ -152,6 +245,9 @@ exports.Line = class Line {
|
|
|
152
245
|
return value;
|
|
153
246
|
}
|
|
154
247
|
|
|
248
|
+
/**
|
|
249
|
+
* @returns {number} The measured width of the line text.
|
|
250
|
+
*/
|
|
155
251
|
get currentWidth() {
|
|
156
252
|
return (
|
|
157
253
|
this._pathOptions.font.calculateTextDimensions(this.value, this.size)
|
|
@@ -159,6 +255,9 @@ exports.Line = class Line {
|
|
|
159
255
|
);
|
|
160
256
|
}
|
|
161
257
|
|
|
258
|
+
/**
|
|
259
|
+
* @returns {number} The sum of the measured word widths.
|
|
260
|
+
*/
|
|
162
261
|
get textWidth() {
|
|
163
262
|
return this.wordObjects.reduce((width, word) => {
|
|
164
263
|
width += word.dimensions.xMax;
|
|
@@ -166,11 +265,17 @@ exports.Line = class Line {
|
|
|
166
265
|
}, 0);
|
|
167
266
|
}
|
|
168
267
|
|
|
268
|
+
/**
|
|
269
|
+
* @returns {number} The available width.
|
|
270
|
+
*/
|
|
169
271
|
get width() {
|
|
170
272
|
return this._width;
|
|
171
273
|
}
|
|
172
274
|
|
|
173
275
|
// dynamic adjust height based on word height?
|
|
276
|
+
/**
|
|
277
|
+
* @returns {number} The fixed height, or the measured text height plus 20.
|
|
278
|
+
*/
|
|
174
279
|
get height() {
|
|
175
280
|
if (this._height) {
|
|
176
281
|
return this._height;
|
|
@@ -187,6 +292,12 @@ exports.Line = class Line {
|
|
|
187
292
|
* Get the offset for a text box.
|
|
188
293
|
* @private
|
|
189
294
|
* @todo handle page margin and padding
|
|
295
|
+
* @param {Object} textBox - The laid-out text box: width, height, textHeight,
|
|
296
|
+
* firstLineHeight and isSimpleText.
|
|
297
|
+
* @param {Object} [options] - The text options.
|
|
298
|
+
* @param {string} [options.align] - A `Recipe.HorizontalAlign` value,
|
|
299
|
+
* optionally followed by a space and a `Recipe.VerticalAlign` value.
|
|
300
|
+
* @returns {{offsetX: number, offsetY: number}} The offset from the placement point.
|
|
190
301
|
*/
|
|
191
302
|
exports._getTextBoxOffset = function _getTextBoxOffset(textBox, options = {}) {
|
|
192
303
|
let offsetX = 0;
|
|
@@ -196,10 +307,10 @@ exports._getTextBoxOffset = function _getTextBoxOffset(textBox, options = {}) {
|
|
|
196
307
|
const alignments = options.align.split(" ");
|
|
197
308
|
if (alignments[0]) {
|
|
198
309
|
switch (alignments[0]) {
|
|
199
|
-
case
|
|
310
|
+
case HorizontalAlign.CENTER:
|
|
200
311
|
offsetX = (-1 * width) / 2;
|
|
201
312
|
break;
|
|
202
|
-
case
|
|
313
|
+
case HorizontalAlign.RIGHT:
|
|
203
314
|
offsetX = -width;
|
|
204
315
|
break;
|
|
205
316
|
default:
|
|
@@ -208,12 +319,12 @@ exports._getTextBoxOffset = function _getTextBoxOffset(textBox, options = {}) {
|
|
|
208
319
|
if (alignments[1]) {
|
|
209
320
|
height = height || textHeight;
|
|
210
321
|
switch (alignments[1]) {
|
|
211
|
-
case
|
|
322
|
+
case VerticalAlign.CENTER:
|
|
212
323
|
offsetY = textBox.isSimpleText
|
|
213
324
|
? -textBox.firstLineHeight / 2
|
|
214
325
|
: height / 2 + offsetY;
|
|
215
326
|
break;
|
|
216
|
-
case
|
|
327
|
+
case VerticalAlign.BOTTOM:
|
|
217
328
|
offsetY = height + offsetY;
|
|
218
329
|
break;
|
|
219
330
|
default:
|
|
@@ -237,9 +348,14 @@ exports._getTextBoxOffset = function _getTextBoxOffset(textBox, options = {}) {
|
|
|
237
348
|
* @param {string} [options.font='helvetica'] - name of font from which measurements are to be taken
|
|
238
349
|
* @param {number} [options.size=14] - size of font to be used in taking measurements
|
|
239
350
|
* @param {number} [options.charSpace=0] - character spacing being applied to the given text.
|
|
351
|
+
* @param {boolean} [options.bold] - Measure with the bold style of the font.
|
|
352
|
+
* @param {boolean} [options.italic] - Measure with the italic style of the font.
|
|
240
353
|
* @returns {Object} measurement components of given text: width, height, xMin, xMax, yMin, yMax
|
|
354
|
+
* @throws {Error} If the font file cannot be loaded.
|
|
241
355
|
*/
|
|
242
356
|
exports.textDimensions = function textDimensions(text, options = {}) {
|
|
357
|
+
// null options act like omitted options.
|
|
358
|
+
if (options === null) options = {};
|
|
243
359
|
const font = this._getFont(options);
|
|
244
360
|
let dimensions = {};
|
|
245
361
|
let charSpaces = 0;
|
|
@@ -270,6 +386,15 @@ exports.textDimensions = function textDimensions(text, options = {}) {
|
|
|
270
386
|
* @param {Object} [options] - The column options.
|
|
271
387
|
*/
|
|
272
388
|
exports.Column = class Column {
|
|
389
|
+
/**
|
|
390
|
+
* @param {number} x - The x coordinate.
|
|
391
|
+
* @param {number} y - The y coordinate.
|
|
392
|
+
* @param {number} width - The column width.
|
|
393
|
+
* @param {number} [height] - The column height; unlimited when omitted.
|
|
394
|
+
* @param {string} [text=''] - The column heading; defaults to the field.
|
|
395
|
+
* @param {string} [field=''] - The associated data field.
|
|
396
|
+
* @param {Object} [options] - The column options; `cell` becomes the text box.
|
|
397
|
+
*/
|
|
273
398
|
constructor(x, y, width, height, text = "", field = "", options = {}) {
|
|
274
399
|
this._x = x;
|
|
275
400
|
this._y = y;
|
|
@@ -294,7 +419,10 @@ exports.Column = class Column {
|
|
|
294
419
|
if (!this._options.header || typeof this._options.header === "boolean") {
|
|
295
420
|
this._options.header = {
|
|
296
421
|
bold: true,
|
|
297
|
-
textBox: {
|
|
422
|
+
textBox: {
|
|
423
|
+
padding: 2,
|
|
424
|
+
textAlign: `${HorizontalAlign.CENTER} ${VerticalAlign.CENTER}`,
|
|
425
|
+
},
|
|
298
426
|
};
|
|
299
427
|
}
|
|
300
428
|
|
|
@@ -303,39 +431,75 @@ exports.Column = class Column {
|
|
|
303
431
|
}
|
|
304
432
|
}
|
|
305
433
|
|
|
434
|
+
/**
|
|
435
|
+
* @returns {number} The column width.
|
|
436
|
+
*/
|
|
306
437
|
get width() {
|
|
307
438
|
return this._width;
|
|
308
439
|
}
|
|
440
|
+
/**
|
|
441
|
+
* @returns {number} The column height.
|
|
442
|
+
*/
|
|
309
443
|
get height() {
|
|
310
444
|
return this._height;
|
|
311
445
|
}
|
|
446
|
+
/**
|
|
447
|
+
* @returns {number} The column x coordinate.
|
|
448
|
+
*/
|
|
312
449
|
get x() {
|
|
313
450
|
return this._x;
|
|
314
451
|
}
|
|
452
|
+
/**
|
|
453
|
+
* @param {number} x - The new x coordinate.
|
|
454
|
+
*/
|
|
315
455
|
set x(x) {
|
|
316
456
|
this._x = x;
|
|
317
457
|
}
|
|
458
|
+
/**
|
|
459
|
+
* @returns {number} The column y coordinate.
|
|
460
|
+
*/
|
|
318
461
|
get y() {
|
|
319
462
|
return this._y;
|
|
320
463
|
}
|
|
464
|
+
/**
|
|
465
|
+
* @returns {number[]} The column [x, y] position.
|
|
466
|
+
*/
|
|
321
467
|
get position() {
|
|
322
468
|
return [this._x, this._y];
|
|
323
469
|
}
|
|
470
|
+
/**
|
|
471
|
+
* @param {number[]} pos - The new [x, y] position.
|
|
472
|
+
*/
|
|
324
473
|
set position(pos) {
|
|
325
474
|
[this._x, this._y] = pos;
|
|
326
475
|
}
|
|
476
|
+
/**
|
|
477
|
+
* @returns {number} The gap after the column.
|
|
478
|
+
*/
|
|
327
479
|
get gap() {
|
|
328
480
|
return this._gap;
|
|
329
481
|
}
|
|
482
|
+
/**
|
|
483
|
+
* @param {number} gap - The new gap after the column.
|
|
484
|
+
*/
|
|
330
485
|
set gap(gap) {
|
|
331
486
|
this._gap = gap;
|
|
332
487
|
}
|
|
488
|
+
/**
|
|
489
|
+
* @returns {string} The associated data field.
|
|
490
|
+
*/
|
|
333
491
|
get field() {
|
|
334
492
|
return this._field;
|
|
335
493
|
}
|
|
494
|
+
/**
|
|
495
|
+
* @returns {string} The column heading.
|
|
496
|
+
*/
|
|
336
497
|
get text() {
|
|
337
498
|
return this._text;
|
|
338
499
|
}
|
|
500
|
+
/**
|
|
501
|
+
* @returns {Object} The column text options.
|
|
502
|
+
*/
|
|
339
503
|
get options() {
|
|
340
504
|
return this._options;
|
|
341
505
|
}
|