pdfkit 0.15.1 → 0.16.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +21 -0
- package/README.md +2 -2
- package/js/pdfkit.es.js +148 -60
- package/js/pdfkit.es.js.map +1 -1
- package/js/pdfkit.js +146 -58
- package/js/pdfkit.js.map +1 -1
- package/js/pdfkit.standalone.js +35915 -39326
- package/package.json +29 -28
package/js/pdfkit.js
CHANGED
|
@@ -52,19 +52,39 @@ class PDFTree {
|
|
|
52
52
|
out.push('>>');
|
|
53
53
|
return out.join('\n');
|
|
54
54
|
}
|
|
55
|
-
_compareKeys(
|
|
55
|
+
_compareKeys(/*a, b*/
|
|
56
56
|
) {
|
|
57
57
|
throw new Error('Must be implemented by subclasses');
|
|
58
58
|
}
|
|
59
59
|
_keysName() {
|
|
60
60
|
throw new Error('Must be implemented by subclasses');
|
|
61
61
|
}
|
|
62
|
-
_dataForKey(
|
|
62
|
+
_dataForKey(/*k*/
|
|
63
63
|
) {
|
|
64
64
|
throw new Error('Must be implemented by subclasses');
|
|
65
65
|
}
|
|
66
66
|
}
|
|
67
67
|
|
|
68
|
+
class SpotColor {
|
|
69
|
+
constructor(doc, name, C, M, Y, K) {
|
|
70
|
+
this.id = 'CS' + Object.keys(doc.spotColors).length;
|
|
71
|
+
this.name = name;
|
|
72
|
+
this.values = [C, M, Y, K];
|
|
73
|
+
this.ref = doc.ref(['Separation', this.name, 'DeviceCMYK', {
|
|
74
|
+
Range: [0, 1, 0, 1, 0, 1, 0, 1],
|
|
75
|
+
C0: [0, 0, 0, 0],
|
|
76
|
+
C1: this.values.map(value => value / 100),
|
|
77
|
+
FunctionType: 2,
|
|
78
|
+
Domain: [0, 1],
|
|
79
|
+
N: 1
|
|
80
|
+
}]);
|
|
81
|
+
this.ref.end();
|
|
82
|
+
}
|
|
83
|
+
toString() {
|
|
84
|
+
return `${this.ref.id} 0 R`;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
68
88
|
/*
|
|
69
89
|
PDFObject - converts JavaScript types into their corresponding PDF types.
|
|
70
90
|
By Devon Govett
|
|
@@ -136,7 +156,7 @@ class PDFObject {
|
|
|
136
156
|
// Buffers are converted to PDF hex strings
|
|
137
157
|
} else if (Buffer.isBuffer(object)) {
|
|
138
158
|
return `<${object.toString('hex')}>`;
|
|
139
|
-
} else if (object instanceof PDFAbstractReference || object instanceof PDFTree) {
|
|
159
|
+
} else if (object instanceof PDFAbstractReference || object instanceof PDFTree || object instanceof SpotColor) {
|
|
140
160
|
return object.toString();
|
|
141
161
|
} else if (object instanceof Date) {
|
|
142
162
|
let string = `D:${pad(object.getUTCFullYear(), 4)}` + pad(object.getUTCMonth() + 1, 2) + pad(object.getUTCDate(), 2) + pad(object.getUTCHours(), 2) + pad(object.getUTCMinutes(), 2) + pad(object.getUTCSeconds(), 2) + 'Z';
|
|
@@ -190,7 +210,7 @@ class PDFReference extends PDFAbstractReference {
|
|
|
190
210
|
this.buffer = [];
|
|
191
211
|
}
|
|
192
212
|
write(chunk) {
|
|
193
|
-
if (!
|
|
213
|
+
if (!(chunk instanceof Uint8Array)) {
|
|
194
214
|
chunk = Buffer.from(chunk + '\n', 'binary');
|
|
195
215
|
}
|
|
196
216
|
this.uncompressedLength += chunk.length;
|
|
@@ -378,8 +398,20 @@ class PDFPage {
|
|
|
378
398
|
write(chunk) {
|
|
379
399
|
return this.content.write(chunk);
|
|
380
400
|
}
|
|
401
|
+
|
|
402
|
+
// Set tab order if document is tagged for accessibility.
|
|
403
|
+
_setTabOrder() {
|
|
404
|
+
if (!this.dictionary.Tabs && this.document.hasMarkInfoDictionary()) {
|
|
405
|
+
this.dictionary.data.Tabs = 'S';
|
|
406
|
+
}
|
|
407
|
+
}
|
|
381
408
|
end() {
|
|
409
|
+
this._setTabOrder();
|
|
382
410
|
this.dictionary.end();
|
|
411
|
+
this.resources.data.ColorSpace = this.resources.data.ColorSpace || {};
|
|
412
|
+
for (let color of Object.values(this.document.spotColors)) {
|
|
413
|
+
this.resources.data.ColorSpace[color.id] = color;
|
|
414
|
+
}
|
|
383
415
|
this.resources.end();
|
|
384
416
|
return this.content.end();
|
|
385
417
|
}
|
|
@@ -992,9 +1024,9 @@ function wordArrayToBuffer(wordArray) {
|
|
|
992
1024
|
const PASSWORD_PADDING = [0x28, 0xbf, 0x4e, 0x5e, 0x4e, 0x75, 0x8a, 0x41, 0x64, 0x00, 0x4e, 0x56, 0xff, 0xfa, 0x01, 0x08, 0x2e, 0x2e, 0x00, 0xb6, 0xd0, 0x68, 0x3e, 0x80, 0x2f, 0x0c, 0xa9, 0xfe, 0x64, 0x53, 0x69, 0x7a];
|
|
993
1025
|
|
|
994
1026
|
const {
|
|
995
|
-
number
|
|
1027
|
+
number: number$2
|
|
996
1028
|
} = PDFObject;
|
|
997
|
-
class PDFGradient {
|
|
1029
|
+
class PDFGradient$1 {
|
|
998
1030
|
constructor(doc) {
|
|
999
1031
|
this.doc = doc;
|
|
1000
1032
|
this.stops = [];
|
|
@@ -1081,7 +1113,7 @@ class PDFGradient {
|
|
|
1081
1113
|
Type: 'Pattern',
|
|
1082
1114
|
PatternType: 2,
|
|
1083
1115
|
Shading: shader,
|
|
1084
|
-
Matrix: this.matrix.map(number)
|
|
1116
|
+
Matrix: this.matrix.map(number$2)
|
|
1085
1117
|
});
|
|
1086
1118
|
pattern.end();
|
|
1087
1119
|
if (this.stops.some(stop => stop[2] < 1)) {
|
|
@@ -1159,7 +1191,7 @@ class PDFGradient {
|
|
|
1159
1191
|
return this.doc.addContent(`/${this.id} ${op}`);
|
|
1160
1192
|
}
|
|
1161
1193
|
}
|
|
1162
|
-
class PDFLinearGradient extends PDFGradient {
|
|
1194
|
+
class PDFLinearGradient$1 extends PDFGradient$1 {
|
|
1163
1195
|
constructor(doc, x1, y1, x2, y2) {
|
|
1164
1196
|
super(doc);
|
|
1165
1197
|
this.x1 = x1;
|
|
@@ -1177,10 +1209,10 @@ class PDFLinearGradient extends PDFGradient {
|
|
|
1177
1209
|
});
|
|
1178
1210
|
}
|
|
1179
1211
|
opacityGradient() {
|
|
1180
|
-
return new PDFLinearGradient(this.doc, this.x1, this.y1, this.x2, this.y2);
|
|
1212
|
+
return new PDFLinearGradient$1(this.doc, this.x1, this.y1, this.x2, this.y2);
|
|
1181
1213
|
}
|
|
1182
1214
|
}
|
|
1183
|
-
class PDFRadialGradient extends PDFGradient {
|
|
1215
|
+
class PDFRadialGradient$1 extends PDFGradient$1 {
|
|
1184
1216
|
constructor(doc, x1, y1, r1, x2, y2, r2) {
|
|
1185
1217
|
super(doc);
|
|
1186
1218
|
this.doc = doc;
|
|
@@ -1201,13 +1233,13 @@ class PDFRadialGradient extends PDFGradient {
|
|
|
1201
1233
|
});
|
|
1202
1234
|
}
|
|
1203
1235
|
opacityGradient() {
|
|
1204
|
-
return new PDFRadialGradient(this.doc, this.x1, this.y1, this.r1, this.x2, this.y2, this.r2);
|
|
1236
|
+
return new PDFRadialGradient$1(this.doc, this.x1, this.y1, this.r1, this.x2, this.y2, this.r2);
|
|
1205
1237
|
}
|
|
1206
1238
|
}
|
|
1207
1239
|
var Gradient = {
|
|
1208
|
-
PDFGradient,
|
|
1209
|
-
PDFLinearGradient,
|
|
1210
|
-
PDFRadialGradient
|
|
1240
|
+
PDFGradient: PDFGradient$1,
|
|
1241
|
+
PDFLinearGradient: PDFLinearGradient$1,
|
|
1242
|
+
PDFRadialGradient: PDFRadialGradient$1
|
|
1211
1243
|
};
|
|
1212
1244
|
|
|
1213
1245
|
/*
|
|
@@ -1215,7 +1247,7 @@ PDF tiling pattern support. Uncolored only.
|
|
|
1215
1247
|
*/
|
|
1216
1248
|
|
|
1217
1249
|
const underlyingColorSpaces = ['DeviceCMYK', 'DeviceRGB'];
|
|
1218
|
-
class PDFTilingPattern {
|
|
1250
|
+
class PDFTilingPattern$1 {
|
|
1219
1251
|
constructor(doc, bBox, xStep, yStep, stream) {
|
|
1220
1252
|
this.doc = doc;
|
|
1221
1253
|
this.bBox = bBox;
|
|
@@ -1293,19 +1325,20 @@ class PDFTilingPattern {
|
|
|
1293
1325
|
}
|
|
1294
1326
|
}
|
|
1295
1327
|
var pattern = {
|
|
1296
|
-
PDFTilingPattern
|
|
1328
|
+
PDFTilingPattern: PDFTilingPattern$1
|
|
1297
1329
|
};
|
|
1298
1330
|
|
|
1299
1331
|
const {
|
|
1300
|
-
PDFGradient
|
|
1301
|
-
PDFLinearGradient
|
|
1302
|
-
PDFRadialGradient
|
|
1332
|
+
PDFGradient,
|
|
1333
|
+
PDFLinearGradient,
|
|
1334
|
+
PDFRadialGradient
|
|
1303
1335
|
} = Gradient;
|
|
1304
1336
|
const {
|
|
1305
|
-
PDFTilingPattern
|
|
1337
|
+
PDFTilingPattern
|
|
1306
1338
|
} = pattern;
|
|
1307
1339
|
var ColorMixin = {
|
|
1308
1340
|
initColor() {
|
|
1341
|
+
this.spotColors = {};
|
|
1309
1342
|
// The opacity dictionaries
|
|
1310
1343
|
this._opacityRegistry = {};
|
|
1311
1344
|
this._opacityCount = 0;
|
|
@@ -1322,6 +1355,8 @@ var ColorMixin = {
|
|
|
1322
1355
|
color = [hex >> 16, hex >> 8 & 0xff, hex & 0xff];
|
|
1323
1356
|
} else if (namedColors[color]) {
|
|
1324
1357
|
color = namedColors[color];
|
|
1358
|
+
} else if (this.spotColors[color]) {
|
|
1359
|
+
return this.spotColors[color];
|
|
1325
1360
|
}
|
|
1326
1361
|
}
|
|
1327
1362
|
if (Array.isArray(color)) {
|
|
@@ -1337,11 +1372,11 @@ var ColorMixin = {
|
|
|
1337
1372
|
return null;
|
|
1338
1373
|
},
|
|
1339
1374
|
_setColor(color, stroke) {
|
|
1340
|
-
if (color instanceof PDFGradient
|
|
1375
|
+
if (color instanceof PDFGradient) {
|
|
1341
1376
|
color.apply(stroke);
|
|
1342
1377
|
return true;
|
|
1343
1378
|
// see if tiling pattern, decode & apply it it
|
|
1344
|
-
} else if (Array.isArray(color) && color[0] instanceof PDFTilingPattern
|
|
1379
|
+
} else if (Array.isArray(color) && color[0] instanceof PDFTilingPattern) {
|
|
1345
1380
|
color[0].apply(stroke, color[1]);
|
|
1346
1381
|
return true;
|
|
1347
1382
|
}
|
|
@@ -1356,8 +1391,12 @@ var ColorMixin = {
|
|
|
1356
1391
|
const op = stroke ? 'SCN' : 'scn';
|
|
1357
1392
|
const space = this._getColorSpace(color);
|
|
1358
1393
|
this._setColorSpace(space, stroke);
|
|
1359
|
-
color
|
|
1360
|
-
|
|
1394
|
+
if (color instanceof SpotColor) {
|
|
1395
|
+
this.page.colorSpaces[color.id] = color.ref;
|
|
1396
|
+
this.addContent(`1 ${op}`);
|
|
1397
|
+
} else {
|
|
1398
|
+
this.addContent(`${color.join(' ')} ${op}`);
|
|
1399
|
+
}
|
|
1361
1400
|
return true;
|
|
1362
1401
|
},
|
|
1363
1402
|
_setColorSpace(space, stroke) {
|
|
@@ -1365,6 +1404,9 @@ var ColorMixin = {
|
|
|
1365
1404
|
return this.addContent(`/${space} ${op}`);
|
|
1366
1405
|
},
|
|
1367
1406
|
_getColorSpace(color) {
|
|
1407
|
+
if (color instanceof SpotColor) {
|
|
1408
|
+
return color.id;
|
|
1409
|
+
}
|
|
1368
1410
|
return color.length === 4 ? 'DeviceCMYK' : 'DeviceRGB';
|
|
1369
1411
|
},
|
|
1370
1412
|
fillColor(color, opacity) {
|
|
@@ -1431,13 +1473,18 @@ var ColorMixin = {
|
|
|
1431
1473
|
return this.addContent(`/${name} gs`);
|
|
1432
1474
|
},
|
|
1433
1475
|
linearGradient(x1, y1, x2, y2) {
|
|
1434
|
-
return new PDFLinearGradient
|
|
1476
|
+
return new PDFLinearGradient(this, x1, y1, x2, y2);
|
|
1435
1477
|
},
|
|
1436
1478
|
radialGradient(x1, y1, r1, x2, y2, r2) {
|
|
1437
|
-
return new PDFRadialGradient
|
|
1479
|
+
return new PDFRadialGradient(this, x1, y1, r1, x2, y2, r2);
|
|
1438
1480
|
},
|
|
1439
1481
|
pattern(bbox, xStep, yStep, stream) {
|
|
1440
|
-
return new PDFTilingPattern
|
|
1482
|
+
return new PDFTilingPattern(this, bbox, xStep, yStep, stream);
|
|
1483
|
+
},
|
|
1484
|
+
addSpotColor(name, C, M, Y, K) {
|
|
1485
|
+
const color = new SpotColor(this, name, C, M, Y, K);
|
|
1486
|
+
this.spotColors[name] = color;
|
|
1487
|
+
return this;
|
|
1441
1488
|
}
|
|
1442
1489
|
};
|
|
1443
1490
|
var namedColors = {
|
|
@@ -2677,7 +2724,7 @@ class EmbeddedFont extends PDFFont {
|
|
|
2677
2724
|
if (isCFF) {
|
|
2678
2725
|
fontFile.data.Subtype = 'CIDFontType0C';
|
|
2679
2726
|
}
|
|
2680
|
-
|
|
2727
|
+
fontFile.end(this.subset.encode());
|
|
2681
2728
|
const familyClass = ((this.font['OS/2'] != null ? this.font['OS/2'].sFamilyClass : undefined) || 0) >> 8;
|
|
2682
2729
|
let flags = 0;
|
|
2683
2730
|
if (this.font.post.isFixedPitch) {
|
|
@@ -2696,7 +2743,7 @@ class EmbeddedFont extends PDFFont {
|
|
|
2696
2743
|
|
|
2697
2744
|
// generate a tag (6 uppercase letters. 17 is the char code offset from '0' to 'A'. 73 will map to 'Z')
|
|
2698
2745
|
const tag = [1, 2, 3, 4, 5, 6].map(i => String.fromCharCode((this.id.charCodeAt(i) || 73) + 17)).join('');
|
|
2699
|
-
const name = tag + '+' + this.font.postscriptName;
|
|
2746
|
+
const name = tag + '+' + this.font.postscriptName.replaceAll(' ', '_');
|
|
2700
2747
|
const {
|
|
2701
2748
|
bbox
|
|
2702
2749
|
} = this.font;
|
|
@@ -2718,7 +2765,7 @@ class EmbeddedFont extends PDFFont {
|
|
|
2718
2765
|
} else {
|
|
2719
2766
|
descriptor.data.FontFile2 = fontFile;
|
|
2720
2767
|
}
|
|
2721
|
-
if (this.document.subset) {
|
|
2768
|
+
if (this.document.subset && this.document.subset === 1) {
|
|
2722
2769
|
const CIDSet = Buffer.from('FFFFFFFFC0', 'hex');
|
|
2723
2770
|
const CIDSetRef = this.document.ref();
|
|
2724
2771
|
CIDSetRef.write(CIDSet);
|
|
@@ -2818,12 +2865,10 @@ class PDFFontFactory {
|
|
|
2818
2865
|
}
|
|
2819
2866
|
src = fs.readFileSync(src);
|
|
2820
2867
|
}
|
|
2821
|
-
if (
|
|
2868
|
+
if (src instanceof Uint8Array) {
|
|
2822
2869
|
font = fontkit.create(src, family);
|
|
2823
|
-
} else if (src instanceof Uint8Array) {
|
|
2824
|
-
font = fontkit.create(Buffer.from(src), family);
|
|
2825
2870
|
} else if (src instanceof ArrayBuffer) {
|
|
2826
|
-
font = fontkit.create(
|
|
2871
|
+
font = fontkit.create(new Uint8Array(src), family);
|
|
2827
2872
|
}
|
|
2828
2873
|
if (font == null) {
|
|
2829
2874
|
throw new Error('Not a supported font format or standard PDF font.');
|
|
@@ -2832,6 +2877,18 @@ class PDFFontFactory {
|
|
|
2832
2877
|
}
|
|
2833
2878
|
}
|
|
2834
2879
|
|
|
2880
|
+
const isEqualFont = (font1, font2) => {
|
|
2881
|
+
// compare font checksum
|
|
2882
|
+
if (font1.font._tables?.head?.checkSumAdjustment !== font2.font._tables?.head?.checkSumAdjustment) {
|
|
2883
|
+
return false;
|
|
2884
|
+
}
|
|
2885
|
+
|
|
2886
|
+
// compare font name table
|
|
2887
|
+
if (JSON.stringify(font1.font._tables?.name?.records) !== JSON.stringify(font2.font._tables?.name?.records)) {
|
|
2888
|
+
return false;
|
|
2889
|
+
}
|
|
2890
|
+
return true;
|
|
2891
|
+
};
|
|
2835
2892
|
var FontsMixin = {
|
|
2836
2893
|
initFonts(defaultFont = 'Helvetica') {
|
|
2837
2894
|
// Lookup table for embedded fonts
|
|
@@ -2884,7 +2941,7 @@ var FontsMixin = {
|
|
|
2884
2941
|
|
|
2885
2942
|
// check for existing font familes with the same name already in the PDF
|
|
2886
2943
|
// useful if the font was passed as a buffer
|
|
2887
|
-
if (font = this._fontFamilies[this._font.name]) {
|
|
2944
|
+
if ((font = this._fontFamilies[this._font.name]) && isEqualFont(this._font, font)) {
|
|
2888
2945
|
this._font = font;
|
|
2889
2946
|
return this;
|
|
2890
2947
|
}
|
|
@@ -2923,12 +2980,13 @@ class LineWrapper extends events.EventEmitter {
|
|
|
2923
2980
|
constructor(document, options) {
|
|
2924
2981
|
super();
|
|
2925
2982
|
this.document = document;
|
|
2926
|
-
this.
|
|
2927
|
-
this.
|
|
2928
|
-
this.
|
|
2983
|
+
this.horizontalScaling = options.horizontalScaling || 100;
|
|
2984
|
+
this.indent = (options.indent || 0) * this.horizontalScaling / 100;
|
|
2985
|
+
this.characterSpacing = (options.characterSpacing || 0) * this.horizontalScaling / 100;
|
|
2986
|
+
this.wordSpacing = (options.wordSpacing === 0) * this.horizontalScaling / 100;
|
|
2929
2987
|
this.columns = options.columns || 1;
|
|
2930
|
-
this.columnGap = options.columnGap != null ? options.columnGap : 18; // 1/4 inch
|
|
2931
|
-
this.lineWidth = (options.width - this.columnGap * (this.columns - 1)) / this.columns;
|
|
2988
|
+
this.columnGap = (options.columnGap != null ? options.columnGap : 18) * this.horizontalScaling / 100; // 1/4 inch
|
|
2989
|
+
this.lineWidth = (options.width * this.horizontalScaling / 100 - this.columnGap * (this.columns - 1)) / this.columns;
|
|
2932
2990
|
this.spaceLeft = this.lineWidth;
|
|
2933
2991
|
this.startX = this.document.x;
|
|
2934
2992
|
this.startY = this.document.y;
|
|
@@ -2953,6 +3011,14 @@ class LineWrapper extends events.EventEmitter {
|
|
|
2953
3011
|
const indent = this.continuedX || this.indent;
|
|
2954
3012
|
this.document.x += indent;
|
|
2955
3013
|
this.lineWidth -= indent;
|
|
3014
|
+
|
|
3015
|
+
// if indentAllLines is set to true
|
|
3016
|
+
// we're not resetting the indentation for this paragraph after the first line
|
|
3017
|
+
if (options.indentAllLines) {
|
|
3018
|
+
return;
|
|
3019
|
+
}
|
|
3020
|
+
|
|
3021
|
+
// otherwise we start the next line without indent
|
|
2956
3022
|
return this.once('line', () => {
|
|
2957
3023
|
this.document.x -= indent;
|
|
2958
3024
|
this.lineWidth += indent;
|
|
@@ -3063,14 +3129,15 @@ class LineWrapper extends events.EventEmitter {
|
|
|
3063
3129
|
}
|
|
3064
3130
|
wrap(text, options) {
|
|
3065
3131
|
// override options from previous continued fragments
|
|
3132
|
+
this.horizontalScaling = options.horizontalScaling || 100;
|
|
3066
3133
|
if (options.indent != null) {
|
|
3067
|
-
this.indent = options.indent;
|
|
3134
|
+
this.indent = options.indent * this.horizontalScaling / 100;
|
|
3068
3135
|
}
|
|
3069
3136
|
if (options.characterSpacing != null) {
|
|
3070
|
-
this.characterSpacing = options.characterSpacing;
|
|
3137
|
+
this.characterSpacing = options.characterSpacing * this.horizontalScaling / 100;
|
|
3071
3138
|
}
|
|
3072
3139
|
if (options.wordSpacing != null) {
|
|
3073
|
-
this.wordSpacing = options.wordSpacing;
|
|
3140
|
+
this.wordSpacing = options.wordSpacing * this.horizontalScaling / 100;
|
|
3074
3141
|
}
|
|
3075
3142
|
if (options.ellipsis != null) {
|
|
3076
3143
|
this.ellipsis = options.ellipsis;
|
|
@@ -3228,7 +3295,7 @@ class LineWrapper extends events.EventEmitter {
|
|
|
3228
3295
|
}
|
|
3229
3296
|
|
|
3230
3297
|
const {
|
|
3231
|
-
number
|
|
3298
|
+
number
|
|
3232
3299
|
} = PDFObject;
|
|
3233
3300
|
var TextMixin = {
|
|
3234
3301
|
initText() {
|
|
@@ -3297,7 +3364,8 @@ var TextMixin = {
|
|
|
3297
3364
|
return this._text(text, x, y, options, this._line);
|
|
3298
3365
|
},
|
|
3299
3366
|
widthOfString(string, options = {}) {
|
|
3300
|
-
|
|
3367
|
+
const horizontalScaling = options.horizontalScaling || 100;
|
|
3368
|
+
return (this._font.widthOfString(string, this._fontSize, options.features) + (options.characterSpacing || 0) * (string.length - 1)) * horizontalScaling / 100;
|
|
3301
3369
|
},
|
|
3302
3370
|
heightOfString(text, options) {
|
|
3303
3371
|
const {
|
|
@@ -3357,11 +3425,10 @@ var TextMixin = {
|
|
|
3357
3425
|
return `${text}.`;
|
|
3358
3426
|
}
|
|
3359
3427
|
};
|
|
3360
|
-
const drawListItem = function (listItem) {
|
|
3428
|
+
const drawListItem = function (listItem, i) {
|
|
3361
3429
|
wrapper = new LineWrapper(this, options);
|
|
3362
3430
|
wrapper.on('line', this._line);
|
|
3363
3431
|
level = 1;
|
|
3364
|
-
let i = 0;
|
|
3365
3432
|
wrapper.once('firstLine', () => {
|
|
3366
3433
|
let item, itemType, labelType, bodyType;
|
|
3367
3434
|
if (options.structParent) {
|
|
@@ -3418,7 +3485,7 @@ var TextMixin = {
|
|
|
3418
3485
|
wrapper.wrap(listItem, options);
|
|
3419
3486
|
};
|
|
3420
3487
|
for (let i = 0; i < items.length; i++) {
|
|
3421
|
-
drawListItem.call(this, items[i]);
|
|
3488
|
+
drawListItem.call(this, items[i], i);
|
|
3422
3489
|
}
|
|
3423
3490
|
return this;
|
|
3424
3491
|
},
|
|
@@ -3471,7 +3538,7 @@ var TextMixin = {
|
|
|
3471
3538
|
this._fragment(text, this.x, this.y, options);
|
|
3472
3539
|
const lineGap = options.lineGap || this._lineGap || 0;
|
|
3473
3540
|
if (!wrapper) {
|
|
3474
|
-
return this.x += this.widthOfString(text);
|
|
3541
|
+
return this.x += this.widthOfString(text, options);
|
|
3475
3542
|
} else {
|
|
3476
3543
|
return this.y += this.currentLineHeight(true) + lineGap;
|
|
3477
3544
|
}
|
|
@@ -3487,6 +3554,7 @@ var TextMixin = {
|
|
|
3487
3554
|
const align = options.align || 'left';
|
|
3488
3555
|
let wordSpacing = options.wordSpacing || 0;
|
|
3489
3556
|
const characterSpacing = options.characterSpacing || 0;
|
|
3557
|
+
const horizontalScaling = options.horizontalScaling || 100;
|
|
3490
3558
|
|
|
3491
3559
|
// text alignments
|
|
3492
3560
|
if (options.width) {
|
|
@@ -3613,10 +3681,10 @@ var TextMixin = {
|
|
|
3613
3681
|
this.addContent('BT');
|
|
3614
3682
|
|
|
3615
3683
|
// text position
|
|
3616
|
-
this.addContent(`1 0 0 1 ${number
|
|
3684
|
+
this.addContent(`1 0 0 1 ${number(x)} ${number(y)} Tm`);
|
|
3617
3685
|
|
|
3618
3686
|
// font and font size
|
|
3619
|
-
this.addContent(`/${this._font.id} ${number
|
|
3687
|
+
this.addContent(`/${this._font.id} ${number(this._fontSize)} Tf`);
|
|
3620
3688
|
|
|
3621
3689
|
// rendering mode
|
|
3622
3690
|
const mode = options.fill && options.stroke ? 2 : options.stroke ? 1 : 0;
|
|
@@ -3626,7 +3694,12 @@ var TextMixin = {
|
|
|
3626
3694
|
|
|
3627
3695
|
// Character spacing
|
|
3628
3696
|
if (characterSpacing) {
|
|
3629
|
-
this.addContent(`${number
|
|
3697
|
+
this.addContent(`${number(characterSpacing)} Tc`);
|
|
3698
|
+
}
|
|
3699
|
+
|
|
3700
|
+
// Horizontal scaling
|
|
3701
|
+
if (horizontalScaling !== 100) {
|
|
3702
|
+
this.addContent(`${horizontalScaling} Tz`);
|
|
3630
3703
|
}
|
|
3631
3704
|
|
|
3632
3705
|
// Add the actual text
|
|
@@ -3668,7 +3741,7 @@ var TextMixin = {
|
|
|
3668
3741
|
if (last < cur) {
|
|
3669
3742
|
const hex = encoded.slice(last, cur).join('');
|
|
3670
3743
|
const advance = positions[cur - 1].xAdvance - positions[cur - 1].advanceWidth;
|
|
3671
|
-
commands.push(`<${hex}> ${number
|
|
3744
|
+
commands.push(`<${hex}> ${number(-advance)}`);
|
|
3672
3745
|
}
|
|
3673
3746
|
return last = cur;
|
|
3674
3747
|
};
|
|
@@ -3690,13 +3763,13 @@ var TextMixin = {
|
|
|
3690
3763
|
flush(i);
|
|
3691
3764
|
|
|
3692
3765
|
// Move the text position and flush just the current character
|
|
3693
|
-
this.addContent(`1 0 0 1 ${number
|
|
3766
|
+
this.addContent(`1 0 0 1 ${number(x + pos.xOffset * scale)} ${number(y + pos.yOffset * scale)} Tm`);
|
|
3694
3767
|
flush(i + 1);
|
|
3695
3768
|
hadOffset = true;
|
|
3696
3769
|
} else {
|
|
3697
3770
|
// If the last character had an offset, reset the text position
|
|
3698
3771
|
if (hadOffset) {
|
|
3699
|
-
this.addContent(`1 0 0 1 ${number
|
|
3772
|
+
this.addContent(`1 0 0 1 ${number(x)} ${number(y)} Tm`);
|
|
3700
3773
|
hadOffset = false;
|
|
3701
3774
|
}
|
|
3702
3775
|
|
|
@@ -4199,7 +4272,9 @@ var AnnotationsMixin = {
|
|
|
4199
4272
|
note(x, y, w, h, contents, options = {}) {
|
|
4200
4273
|
options.Subtype = 'Text';
|
|
4201
4274
|
options.Contents = new String(contents);
|
|
4202
|
-
options.Name
|
|
4275
|
+
if (options.Name == null) {
|
|
4276
|
+
options.Name = 'Comment';
|
|
4277
|
+
}
|
|
4203
4278
|
if (options.color == null) {
|
|
4204
4279
|
options.color = [243, 223, 92];
|
|
4205
4280
|
}
|
|
@@ -4702,6 +4777,9 @@ var MarkingsMixin = {
|
|
|
4702
4777
|
}
|
|
4703
4778
|
return this._root.data.MarkInfo;
|
|
4704
4779
|
},
|
|
4780
|
+
hasMarkInfoDictionary() {
|
|
4781
|
+
return !!this._root.data.MarkInfo;
|
|
4782
|
+
},
|
|
4705
4783
|
getStructTreeRoot() {
|
|
4706
4784
|
if (!this._root.data.StructTreeRoot) {
|
|
4707
4785
|
this._root.data.StructTreeRoot = this.ref({
|
|
@@ -5032,7 +5110,7 @@ var AcroFormMixin = {
|
|
|
5032
5110
|
},
|
|
5033
5111
|
_resolveFont(options) {
|
|
5034
5112
|
// add current font to document-level AcroForm dict if necessary
|
|
5035
|
-
if (this._acroform.fonts[this._font.id]
|
|
5113
|
+
if (this._acroform.fonts[this._font.id] == null) {
|
|
5036
5114
|
this._acroform.fonts[this._font.id] = this._font.ref();
|
|
5037
5115
|
}
|
|
5038
5116
|
|
|
@@ -5104,10 +5182,12 @@ var AttachmentsMixin = {
|
|
|
5104
5182
|
* * options.hidden: if true, do not add attachment to EmbeddedFiles dictionary. Useful for file attachment annotations
|
|
5105
5183
|
* * options.creationDate: override creation date
|
|
5106
5184
|
* * options.modifiedDate: override modified date
|
|
5185
|
+
* * options.relationship: Relationship between the PDF document and its attached file. Can be 'Alternative', 'Data', 'Source', 'Supplement' or 'Unspecified'.
|
|
5107
5186
|
* @returns filespec reference
|
|
5108
5187
|
*/
|
|
5109
5188
|
file(src, options = {}) {
|
|
5110
5189
|
options.name = options.name || src;
|
|
5190
|
+
options.relationship = options.relationship || 'Unspecified';
|
|
5111
5191
|
const refBody = {
|
|
5112
5192
|
Type: 'EmbeddedFile',
|
|
5113
5193
|
Params: {}
|
|
@@ -5178,6 +5258,7 @@ var AttachmentsMixin = {
|
|
|
5178
5258
|
// add filespec for embedded file
|
|
5179
5259
|
const fileSpecBody = {
|
|
5180
5260
|
Type: 'Filespec',
|
|
5261
|
+
AFRelationship: options.relationship,
|
|
5181
5262
|
F: new String(options.name),
|
|
5182
5263
|
EF: {
|
|
5183
5264
|
F: ref
|
|
@@ -5192,13 +5273,20 @@ var AttachmentsMixin = {
|
|
|
5192
5273
|
if (!options.hidden) {
|
|
5193
5274
|
this.addNamedEmbeddedFile(options.name, filespec);
|
|
5194
5275
|
}
|
|
5276
|
+
|
|
5277
|
+
// Add file to the catalogue to be PDF/A3 compliant
|
|
5278
|
+
if (this._root.data.AF) {
|
|
5279
|
+
this._root.data.AF.push(filespec);
|
|
5280
|
+
} else {
|
|
5281
|
+
this._root.data.AF = [filespec];
|
|
5282
|
+
}
|
|
5195
5283
|
return filespec;
|
|
5196
5284
|
}
|
|
5197
5285
|
};
|
|
5198
5286
|
|
|
5199
5287
|
/** check two embedded file metadata objects for equality */
|
|
5200
5288
|
function isEqual(a, b) {
|
|
5201
|
-
return a.Subtype === b.Subtype && a.Params.CheckSum.toString() === b.Params.CheckSum.toString() && a.Params.Size === b.Params.Size && a.Params.CreationDate.getTime() === b.Params.CreationDate.getTime() && a.Params.ModDate.getTime() === b.Params.ModDate.getTime();
|
|
5289
|
+
return a.Subtype === b.Subtype && a.Params.CheckSum.toString() === b.Params.CheckSum.toString() && a.Params.Size === b.Params.Size && a.Params.CreationDate.getTime() === b.Params.CreationDate.getTime() && (a.Params.ModDate === undefined && b.Params.ModDate === undefined || a.Params.ModDate.getTime() === b.Params.ModDate.getTime());
|
|
5202
5290
|
}
|
|
5203
5291
|
|
|
5204
5292
|
var PDFA = {
|