pdfkit 0.18.0 → 0.19.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/js/pdfkit.es.js CHANGED
@@ -2,11 +2,10 @@ import stream from 'stream';
2
2
  import zlib from 'zlib';
3
3
  import { concatBytes } from '@noble/hashes/utils';
4
4
  import md5 from 'js-md5';
5
- import { sha256 } from '@noble/hashes/sha256';
5
+ import { sha256 } from '@noble/hashes/sha2';
6
6
  import { cbc, ecb } from '@noble/ciphers/aes';
7
7
  import fs from 'fs';
8
- import * as fontkit from 'fontkit';
9
- import { EventEmitter } from 'events';
8
+ import { create } from 'fontkit';
10
9
  import LineBreaker from 'linebreak';
11
10
  import PNG from 'png-js';
12
11
 
@@ -17,8 +16,7 @@ class PDFAbstractReference {
17
16
  }
18
17
 
19
18
  class PDFTree {
20
- constructor() {
21
- let options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
19
+ constructor(options = {}) {
22
20
  this._items = {};
23
21
  this.limits = typeof options.limits === 'boolean' ? options.limits : true;
24
22
  }
@@ -60,7 +58,7 @@ class SpotColor {
60
58
  this.id = 'CS' + Object.keys(doc.spotColors).length;
61
59
  this.name = name;
62
60
  this.values = [C, M, Y, K];
63
- this.ref = doc.ref(['Separation', this.name, 'DeviceCMYK', {
61
+ this.ref = doc.ref(['Separation', escapeName(this.name), 'DeviceCMYK', {
64
62
  Range: [0, 1, 0, 1, 0, 1, 0, 1],
65
63
  C0: [0, 0, 0, 0],
66
64
  C1: this.values.map(value => value / 100),
@@ -76,6 +74,10 @@ class SpotColor {
76
74
  }
77
75
 
78
76
  const pad = (str, length) => (Array(length + 1).join('0') + str).slice(-length);
77
+ const isSafeCharCode = code => {
78
+ if (code > 0x7f) return true;
79
+ return code > 0x20 && code !== 0x7f && code !== 0x23 && code !== 0x25 && code !== 0x28 && code !== 0x29 && code !== 0x2f && code !== 0x3c && code !== 0x3e && code !== 0x5b && code !== 0x5d && code !== 0x7b && code !== 0x7d;
80
+ };
79
81
  const escapableRe = /[\n\r\t\b\f()\\]/g;
80
82
  const escapable = {
81
83
  '\n': '\\n',
@@ -87,6 +89,18 @@ const escapable = {
87
89
  '(': '\\(',
88
90
  ')': '\\)'
89
91
  };
92
+ const escapeName = function (name) {
93
+ let escapedName = '';
94
+ for (const char of name) {
95
+ const code = char.charCodeAt(0);
96
+ if (isSafeCharCode(code)) {
97
+ escapedName += char;
98
+ } else {
99
+ escapedName += `#${code.toString(16).toUpperCase().padStart(2, '0')}`;
100
+ }
101
+ }
102
+ return escapedName;
103
+ };
90
104
  const swapBytes = function (buff) {
91
105
  const l = buff.length;
92
106
  if (l & 0x01) {
@@ -101,8 +115,7 @@ const swapBytes = function (buff) {
101
115
  return buff;
102
116
  };
103
117
  class PDFObject {
104
- static convert(object) {
105
- let encryptFn = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null;
118
+ static convert(object, encryptFn = null) {
106
119
  if (typeof object === 'string') {
107
120
  return `/${object}`;
108
121
  } else if (object instanceof String) {
@@ -164,8 +177,7 @@ class PDFObject {
164
177
  }
165
178
 
166
179
  class PDFReference extends PDFAbstractReference {
167
- constructor(document, id) {
168
- let data = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
180
+ constructor(document, id, data = {}) {
169
181
  super();
170
182
  this.document = document;
171
183
  this.id = id;
@@ -237,9 +249,7 @@ function PDFNumber(n) {
237
249
  }
238
250
  return fArray[0];
239
251
  }
240
- function normalizeSides(sides) {
241
- let defaultDefinition = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : undefined;
242
- let transformer = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : v => v;
252
+ function normalizeSides(sides, defaultDefinition = undefined, transformer = v => v) {
243
253
  if (sides == null || typeof sides === 'object' && Object.keys(sides).length === 0) {
244
254
  sides = defaultDefinition;
245
255
  }
@@ -359,8 +369,7 @@ const SIZES = {
359
369
  TABLOID: [792.0, 1224.0]
360
370
  };
361
371
  class PDFPage {
362
- constructor(document) {
363
- let options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
372
+ constructor(document, options = {}) {
364
373
  this.document = document;
365
374
  this._options = options;
366
375
  this.size = options.size || 'letter';
@@ -466,8 +475,7 @@ function sha256Hash(data) {
466
475
  return sha256(data);
467
476
  }
468
477
 
469
- function aesCbcEncrypt(data, key, iv) {
470
- let padding = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : true;
478
+ function aesCbcEncrypt(data, key, iv, padding = true) {
471
479
  return cbc(key, iv, {
472
480
  disablePadding: !padding
473
481
  }).encrypt(data);
@@ -500,11 +508,7 @@ function rc4(data, key) {
500
508
 
501
509
  function randomBytes(length) {
502
510
  const bytes = new Uint8Array(length);
503
- if (globalThis.crypto?.getRandomValues) {
504
- globalThis.crypto.getRandomValues(bytes);
505
- } else {
506
- require('crypto').randomFillSync(bytes);
507
- }
511
+ globalThis.crypto.getRandomValues(bytes);
508
512
  return bytes;
509
513
  }
510
514
 
@@ -564,8 +568,7 @@ function toCodePoints(input) {
564
568
  }
565
569
  return codepoints;
566
570
  }
567
- function saslprep(input) {
568
- let opts = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
571
+ function saslprep(input, opts = {}) {
569
572
  if (typeof input !== 'string') {
570
573
  throw new TypeError('Expected string.');
571
574
  }
@@ -599,8 +602,7 @@ function saslprep(input) {
599
602
  }
600
603
 
601
604
  class PDFSecurity {
602
- static generateFileID() {
603
- let info = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
605
+ static generateFileID(info = {}) {
604
606
  let infoStr = `${info.CreationDate.getTime()}\n`;
605
607
  for (let key in info) {
606
608
  if (!info.hasOwnProperty(key)) {
@@ -613,15 +615,13 @@ class PDFSecurity {
613
615
  static generateRandomWordArray(bytes) {
614
616
  return randomBytes(bytes);
615
617
  }
616
- static create(document) {
617
- let options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
618
+ static create(document, options = {}) {
618
619
  if (!options.ownerPassword && !options.userPassword) {
619
620
  return null;
620
621
  }
621
622
  return new PDFSecurity(document, options);
622
623
  }
623
- constructor(document) {
624
- let options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
624
+ constructor(document, options = {}) {
625
625
  if (!options.ownerPassword && !options.userPassword) {
626
626
  throw new Error('None of owner password and user password is defined.');
627
627
  }
@@ -770,8 +770,7 @@ class PDFSecurity {
770
770
  this.dictionary.end();
771
771
  }
772
772
  }
773
- function getPermissionsR2() {
774
- let permissionObject = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
773
+ function getPermissionsR2(permissionObject = {}) {
775
774
  let permissions = 0xffffffc0 >> 0;
776
775
  if (permissionObject.printing) {
777
776
  permissions |= 0b000000000100;
@@ -787,8 +786,7 @@ function getPermissionsR2() {
787
786
  }
788
787
  return permissions;
789
788
  }
790
- function getPermissionsR3() {
791
- let permissionObject = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
789
+ function getPermissionsR3(permissionObject = {}) {
792
790
  let permissions = 0xfffff0c0 >> 0;
793
791
  if (permissionObject.printing === 'lowResolution') {
794
792
  permissions |= 0b000000000100;
@@ -906,8 +904,7 @@ function getEncryptedPermissionsR5(permissions, encryptionKey, generateRandomWor
906
904
  data.set(randomPart, 12);
907
905
  return aesEcbEncrypt(data, encryptionKey);
908
906
  }
909
- function processPasswordR2R3R4() {
910
- let password = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : '';
907
+ function processPasswordR2R3R4(password = '') {
911
908
  const out = new Uint8Array(32);
912
909
  const length = password.length;
913
910
  let index = 0;
@@ -925,8 +922,7 @@ function processPasswordR2R3R4() {
925
922
  }
926
923
  return out;
927
924
  }
928
- function processPasswordR5() {
929
- let password = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : '';
925
+ function processPasswordR5(password = '') {
930
926
  password = unescape(encodeURIComponent(saslprep(password)));
931
927
  const length = Math.min(127, password.length);
932
928
  const out = new Uint8Array(length);
@@ -940,7 +936,7 @@ const PASSWORD_PADDING = [0x28, 0xbf, 0x4e, 0x5e, 0x4e, 0x75, 0x8a, 0x41, 0x64,
940
936
  const {
941
937
  number: number$2
942
938
  } = PDFObject;
943
- class PDFGradient$1 {
939
+ let PDFGradient$1 = class PDFGradient {
944
940
  constructor(doc) {
945
941
  this.doc = doc;
946
942
  this.stops = [];
@@ -1098,8 +1094,8 @@ class PDFGradient$1 {
1098
1094
  const op = stroke ? 'SCN' : 'scn';
1099
1095
  return this.doc.addContent(`/${this.id} ${op}`);
1100
1096
  }
1101
- }
1102
- class PDFLinearGradient$1 extends PDFGradient$1 {
1097
+ };
1098
+ let PDFLinearGradient$1 = class PDFLinearGradient extends PDFGradient$1 {
1103
1099
  constructor(doc, x1, y1, x2, y2) {
1104
1100
  super(doc);
1105
1101
  this.x1 = x1;
@@ -1117,10 +1113,10 @@ class PDFLinearGradient$1 extends PDFGradient$1 {
1117
1113
  });
1118
1114
  }
1119
1115
  opacityGradient() {
1120
- return new PDFLinearGradient$1(this.doc, this.x1, this.y1, this.x2, this.y2);
1116
+ return new PDFLinearGradient(this.doc, this.x1, this.y1, this.x2, this.y2);
1121
1117
  }
1122
- }
1123
- class PDFRadialGradient$1 extends PDFGradient$1 {
1118
+ };
1119
+ let PDFRadialGradient$1 = class PDFRadialGradient extends PDFGradient$1 {
1124
1120
  constructor(doc, x1, y1, r1, x2, y2, r2) {
1125
1121
  super(doc);
1126
1122
  this.doc = doc;
@@ -1141,9 +1137,9 @@ class PDFRadialGradient$1 extends PDFGradient$1 {
1141
1137
  });
1142
1138
  }
1143
1139
  opacityGradient() {
1144
- return new PDFRadialGradient$1(this.doc, this.x1, this.y1, this.r1, this.x2, this.y2, this.r2);
1140
+ return new PDFRadialGradient(this.doc, this.x1, this.y1, this.r1, this.x2, this.y2, this.r2);
1145
1141
  }
1146
- }
1142
+ };
1147
1143
  var Gradient = {
1148
1144
  PDFGradient: PDFGradient$1,
1149
1145
  PDFLinearGradient: PDFLinearGradient$1,
@@ -1151,7 +1147,7 @@ var Gradient = {
1151
1147
  };
1152
1148
 
1153
1149
  const underlyingColorSpaces = ['DeviceCMYK', 'DeviceRGB'];
1154
- class PDFTilingPattern$1 {
1150
+ let PDFTilingPattern$1 = class PDFTilingPattern {
1155
1151
  constructor(doc, bBox, xStep, yStep, stream) {
1156
1152
  this.doc = doc;
1157
1153
  this.bBox = bBox;
@@ -1211,7 +1207,7 @@ class PDFTilingPattern$1 {
1211
1207
  const op = stroke ? 'SCN' : 'scn';
1212
1208
  return this.doc.addContent(`${normalizedColor.join(' ')} /${this.id} ${op}`);
1213
1209
  }
1214
- }
1210
+ };
1215
1211
  var pattern = {
1216
1212
  PDFTilingPattern: PDFTilingPattern$1
1217
1213
  };
@@ -1990,8 +1986,7 @@ var VectorMixin = {
1990
1986
  miterLimit(m) {
1991
1987
  return this.addContent(`${number$1(m)} M`);
1992
1988
  },
1993
- dash(length) {
1994
- let options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
1989
+ dash(length, options = {}) {
1995
1990
  const originalLength = length;
1996
1991
  if (!Array.isArray(length)) {
1997
1992
  length = [length, options.space || length];
@@ -2021,21 +2016,42 @@ var VectorMixin = {
2021
2016
  rect(x, y, w, h) {
2022
2017
  return this.addContent(`${number$1(x)} ${number$1(y)} ${number$1(w)} ${number$1(h)} re`);
2023
2018
  },
2024
- roundedRect(x, y, w, h, r) {
2025
- if (r == null) {
2026
- r = 0;
2027
- }
2028
- r = Math.min(r, 0.5 * w, 0.5 * h);
2029
- const c = r * (1.0 - KAPPA);
2030
- this.moveTo(x + r, y);
2031
- this.lineTo(x + w - r, y);
2032
- this.bezierCurveTo(x + w - c, y, x + w, y + c, x + w, y + r);
2033
- this.lineTo(x + w, y + h - r);
2034
- this.bezierCurveTo(x + w, y + h - c, x + w - c, y + h, x + w - r, y + h);
2035
- this.lineTo(x + r, y + h);
2036
- this.bezierCurveTo(x + c, y + h, x, y + h - c, x, y + h - r);
2037
- this.lineTo(x, y + r);
2038
- this.bezierCurveTo(x, y + c, x + c, y, x + r, y);
2019
+ roundedRect(x, y, w, h, borderRadius) {
2020
+ if (borderRadius == null) {
2021
+ borderRadius = 0;
2022
+ }
2023
+ let radii;
2024
+ if (Array.isArray(borderRadius)) {
2025
+ radii = borderRadius.slice(0, 4);
2026
+ } else {
2027
+ radii = [borderRadius, borderRadius, borderRadius, borderRadius];
2028
+ }
2029
+ const limit = Math.min(0.5 * w, 0.5 * h);
2030
+ const rTL = Math.max(0, Math.min(radii[0] || 0, limit));
2031
+ const rTR = Math.max(0, Math.min(radii[1] || 0, limit));
2032
+ const rBR = Math.max(0, Math.min(radii[2] || 0, limit));
2033
+ const rBL = Math.max(0, Math.min(radii[3] || 0, limit));
2034
+ const cpTR = rTR * (1.0 - KAPPA);
2035
+ const cpBR = rBR * (1.0 - KAPPA);
2036
+ const cpBL = rBL * (1.0 - KAPPA);
2037
+ const cpTL = rTL * (1.0 - KAPPA);
2038
+ this.moveTo(x + rTL, y);
2039
+ this.lineTo(x + w - rTR, y);
2040
+ if (rTR > 0) {
2041
+ this.bezierCurveTo(x + w - cpTR, y, x + w, y + cpTR, x + w, y + rTR);
2042
+ }
2043
+ this.lineTo(x + w, y + h - rBR);
2044
+ if (rBR > 0) {
2045
+ this.bezierCurveTo(x + w, y + h - cpBR, x + w - cpBR, y + h, x + w - rBR, y + h);
2046
+ }
2047
+ this.lineTo(x + rBL, y + h);
2048
+ if (rBL > 0) {
2049
+ this.bezierCurveTo(x + cpBL, y + h, x, y + h - cpBL, x, y + h - rBL);
2050
+ }
2051
+ this.lineTo(x, y + rTL);
2052
+ if (rTL > 0) {
2053
+ this.bezierCurveTo(x, y + cpTL, x + cpTL, y, x + rTL, y);
2054
+ }
2039
2055
  return this.closePath();
2040
2056
  },
2041
2057
  ellipse(x, y, r1, r2) {
@@ -2096,10 +2112,7 @@ var VectorMixin = {
2096
2112
  }
2097
2113
  return this;
2098
2114
  },
2099
- polygon() {
2100
- for (var _len = arguments.length, points = new Array(_len), _key = 0; _key < _len; _key++) {
2101
- points[_key] = arguments[_key];
2102
- }
2115
+ polygon(...points) {
2103
2116
  this.moveTo(...(points.shift() || []));
2104
2117
  for (let point of points) {
2105
2118
  this.lineTo(...(point || []));
@@ -2172,8 +2185,7 @@ var VectorMixin = {
2172
2185
  translate(x, y) {
2173
2186
  return this.transform(1, 0, 0, 1, x, y);
2174
2187
  },
2175
- rotate(angle) {
2176
- let options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
2188
+ rotate(angle, options = {}) {
2177
2189
  let y;
2178
2190
  const rad = angle * Math.PI / 180;
2179
2191
  const cos = Math.cos(rad);
@@ -2188,8 +2200,7 @@ var VectorMixin = {
2188
2200
  }
2189
2201
  return this.transform(cos, sin, -sin, cos, x, y);
2190
2202
  },
2191
- scale(xFactor, yFactor) {
2192
- let options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
2203
+ scale(xFactor, yFactor, options = {}) {
2193
2204
  let y;
2194
2205
  if (yFactor == null) {
2195
2206
  yFactor = xFactor;
@@ -2332,7 +2343,7 @@ class AFMFont {
2332
2343
  if (match = line.match(/^Start(\w+)/)) {
2333
2344
  section = match[1];
2334
2345
  continue;
2335
- } else if (match = line.match(/^End(\w+)/)) {
2346
+ } else if (line.match(/^End(\w+)/)) {
2336
2347
  section = '';
2337
2348
  continue;
2338
2349
  }
@@ -2424,8 +2435,7 @@ class PDFFont {
2424
2435
  embed() {
2425
2436
  throw new Error('Must be implemented by subclasses');
2426
2437
  }
2427
- lineHeight(size) {
2428
- let includeGap = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
2438
+ lineHeight(size, includeGap = false) {
2429
2439
  const gap = includeGap ? this.lineGap : 0;
2430
2440
  return (this.ascender + gap - this.descender) / 1000 * size;
2431
2441
  }
@@ -2677,9 +2687,15 @@ class EmbeddedFont extends PDFFont {
2677
2687
  descriptor.data.FontFile2 = fontFile;
2678
2688
  }
2679
2689
  if (this.document.subset && this.document.subset === 1) {
2680
- const CIDSet = Buffer.from('FFFFFFFFC0', 'hex');
2690
+ const maxCID = this.widths.length - 1;
2691
+ const cidSetBuffer = Buffer.alloc(Math.ceil((maxCID + 1) / 8), 0);
2692
+ for (let cid = 0; cid <= maxCID; cid++) {
2693
+ if (this.widths[cid] != null) {
2694
+ cidSetBuffer[Math.floor(cid / 8)] |= 0x80 >> cid % 8;
2695
+ }
2696
+ }
2681
2697
  const CIDSetRef = this.document.ref();
2682
- CIDSetRef.write(CIDSet);
2698
+ CIDSetRef.write(cidSetBuffer);
2683
2699
  CIDSetRef.end();
2684
2700
  descriptor.data.CIDSet = CIDSetRef;
2685
2701
  }
@@ -2771,9 +2787,9 @@ class PDFFontFactory {
2771
2787
  src = fs.readFileSync(src);
2772
2788
  }
2773
2789
  if (src instanceof Uint8Array) {
2774
- font = fontkit.create(src, family);
2790
+ font = create(src, family);
2775
2791
  } else if (src instanceof ArrayBuffer) {
2776
- font = fontkit.create(new Uint8Array(src), family);
2792
+ font = create(new Uint8Array(src), family);
2777
2793
  }
2778
2794
  if (font == null) {
2779
2795
  throw new Error('Not a supported font format or standard PDF font.');
@@ -2792,10 +2808,7 @@ const isEqualFont = (font1, font2) => {
2792
2808
  return true;
2793
2809
  };
2794
2810
  var FontsMixin = {
2795
- initFonts() {
2796
- let defaultFont = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 'Helvetica';
2797
- let defaultFontFamily = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null;
2798
- let defaultFontSize = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 12;
2811
+ initFonts(defaultFont = 'Helvetica', defaultFontFamily = null, defaultFontSize = 12) {
2799
2812
  this._fontFamilies = {};
2800
2813
  this._fontCount = 0;
2801
2814
  this._fontSource = defaultFont;
@@ -2844,9 +2857,12 @@ var FontsMixin = {
2844
2857
  if (cacheKey) {
2845
2858
  this._fontFamilies[cacheKey] = this._font;
2846
2859
  }
2847
- if (this._font.name) {
2860
+ if (this._font.name && !this._fontFamilies[this._font.name]) {
2848
2861
  this._fontFamilies[this._font.name] = this._font;
2849
2862
  }
2863
+ if (!cacheKey && (!this._font.name || this._fontFamilies[this._font.name] !== this._font)) {
2864
+ this._fontFamilies[this._font.id] = this._font;
2865
+ }
2850
2866
  return this;
2851
2867
  },
2852
2868
  fontSize(_fontSize) {
@@ -2863,10 +2879,7 @@ var FontsMixin = {
2863
2879
  };
2864
2880
  return this;
2865
2881
  },
2866
- sizeToPoint(size) {
2867
- let defaultValue = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0;
2868
- let page = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : this.page;
2869
- let percentageWidth = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : undefined;
2882
+ sizeToPoint(size, defaultValue = 0, page = this.page, percentageWidth = undefined) {
2870
2883
  if (!percentageWidth) percentageWidth = this._fontSize;
2871
2884
  if (typeof defaultValue !== 'number') defaultValue = this.sizeToPoint(defaultValue);
2872
2885
  if (size === undefined) return defaultValue;
@@ -2928,9 +2941,9 @@ var FontsMixin = {
2928
2941
 
2929
2942
  const SOFT_HYPHEN = '\u00AD';
2930
2943
  const HYPHEN = '-';
2931
- class LineWrapper extends EventEmitter {
2944
+ class LineWrapper {
2932
2945
  constructor(document, options) {
2933
- super();
2946
+ this._listeners = Object.create(null);
2934
2947
  this.document = document;
2935
2948
  this.horizontalScaling = options.horizontalScaling || 100;
2936
2949
  this.indent = (options.indent || 0) * this.horizontalScaling / 100;
@@ -2986,6 +2999,22 @@ class LineWrapper extends EventEmitter {
2986
2999
  });
2987
3000
  });
2988
3001
  }
3002
+ on(event, listener) {
3003
+ (this._listeners[event] || (this._listeners[event] = [])).push(listener);
3004
+ }
3005
+ once(event, listener) {
3006
+ const wrapper = (...args) => {
3007
+ const listeners = this._listeners[event];
3008
+ listeners.splice(listeners.indexOf(wrapper), 1);
3009
+ listener(...args);
3010
+ };
3011
+ this.on(event, wrapper);
3012
+ }
3013
+ emit(event, ...args) {
3014
+ const listeners = this._listeners[event];
3015
+ if (!listeners) return;
3016
+ for (const listener of listeners.slice()) listener(...args);
3017
+ }
2989
3018
  wordWidth(word) {
2990
3019
  return PDFNumber(this.document.widthOfString(word, this) + this.characterSpacing + this.wordSpacing);
2991
3020
  }
@@ -3051,6 +3080,9 @@ class LineWrapper extends EventEmitter {
3051
3080
  }
3052
3081
  }
3053
3082
  wrap(text, options) {
3083
+ const {
3084
+ document
3085
+ } = this;
3054
3086
  this.horizontalScaling = options.horizontalScaling || 100;
3055
3087
  if (options.indent != null) {
3056
3088
  this.indent = options.indent * this.horizontalScaling / 100;
@@ -3064,24 +3096,20 @@ class LineWrapper extends EventEmitter {
3064
3096
  if (options.ellipsis != null) {
3065
3097
  this.ellipsis = options.ellipsis;
3066
3098
  }
3067
- const nextY = this.document.y + this.document.currentLineHeight(true);
3068
- if (this.document.y > this.maxY || nextY > this.maxY) {
3099
+ const nextY = document.y + document.currentLineHeight(true);
3100
+ if (document.y > this.maxY || nextY > this.maxY) {
3069
3101
  this.nextSection();
3070
3102
  }
3071
3103
  let buffer = '';
3072
3104
  let textWidth = 0;
3073
3105
  let wc = 0;
3074
3106
  let lc = 0;
3075
- let {
3076
- y
3077
- } = this.document;
3107
+ let continueY = document.y;
3078
3108
  const emitLine = () => {
3079
3109
  options.textWidth = textWidth + this.wordSpacing * (wc - 1);
3080
3110
  options.wordCount = wc;
3081
3111
  options.lineWidth = this.lineWidth;
3082
- ({
3083
- y
3084
- } = this.document);
3112
+ continueY = document.y;
3085
3113
  this.emit('line', buffer, options, this);
3086
3114
  return lc++;
3087
3115
  };
@@ -3097,8 +3125,8 @@ class LineWrapper extends EventEmitter {
3097
3125
  wc++;
3098
3126
  }
3099
3127
  if (bk.required || !this.canFit(word, w)) {
3100
- const lh = this.document.currentLineHeight(true);
3101
- if (this.height != null && this.ellipsis && PDFNumber(this.document.y + lh * 2) > this.maxY && this.column >= this.columns) {
3128
+ const lh = document.currentLineHeight(true);
3129
+ if (this.height != null && this.ellipsis && PDFNumber(document.y + lh * 2) > this.maxY && this.column >= this.columns) {
3102
3130
  if (this.ellipsis === true) {
3103
3131
  this.ellipsis = '…';
3104
3132
  }
@@ -3127,7 +3155,7 @@ class LineWrapper extends EventEmitter {
3127
3155
  this.spaceLeft -= this.wordWidth(HYPHEN);
3128
3156
  }
3129
3157
  emitLine();
3130
- if (PDFNumber(this.document.y + lh) > this.maxY) {
3158
+ if (PDFNumber(document.y + lh) > this.maxY) {
3131
3159
  this.emit('sectionEnd', options, this);
3132
3160
  const shouldContinue = this.nextSection();
3133
3161
  if (!shouldContinue) {
@@ -3162,9 +3190,9 @@ class LineWrapper extends EventEmitter {
3162
3190
  this.continuedX = 0;
3163
3191
  }
3164
3192
  this.continuedX += options.textWidth || 0;
3165
- this.document.y = y;
3193
+ document.y = continueY;
3166
3194
  } else {
3167
- this.document.x = this.startX;
3195
+ document.x = this.startX;
3168
3196
  }
3169
3197
  }
3170
3198
  nextSection(options) {
@@ -3272,8 +3300,7 @@ var TextMixin = {
3272
3300
  text(text, x, y, options) {
3273
3301
  return this._text(text, x, y, options, this._line);
3274
3302
  },
3275
- widthOfString(string) {
3276
- let options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
3303
+ widthOfString(string, options = {}) {
3277
3304
  const horizontalScaling = options.horizontalScaling || 100;
3278
3305
  return (this._font.widthOfString(string, this._fontSize, options.features) + (options.characterSpacing || 0) * (string.length - 1)) * horizontalScaling / 100;
3279
3306
  },
@@ -3479,11 +3506,8 @@ var TextMixin = {
3479
3506
  }
3480
3507
  return this;
3481
3508
  },
3482
- _initOptions() {
3483
- let x = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
3484
- let y = arguments.length > 1 ? arguments[1] : undefined;
3485
- let options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
3486
- if (typeof x === 'object') {
3509
+ _initOptions(x = {}, y, options = {}) {
3510
+ if (x && typeof x === 'object') {
3487
3511
  options = x;
3488
3512
  x = null;
3489
3513
  }
@@ -3516,13 +3540,11 @@ var TextMixin = {
3516
3540
  if (result.columnGap == null) {
3517
3541
  result.columnGap = 18;
3518
3542
  }
3519
- result.rotation = Number(options.rotation ?? 0) % 360;
3543
+ result.rotation = Number(result.rotation ?? 0) % 360;
3520
3544
  if (result.rotation < 0) result.rotation += 360;
3521
3545
  return result;
3522
3546
  },
3523
- _line(text) {
3524
- let options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
3525
- let wrapper = arguments.length > 2 ? arguments[2] : undefined;
3547
+ _line(text, options = {}, wrapper) {
3526
3548
  this._fragment(text, this.x, this.y, options);
3527
3549
  if (wrapper) {
3528
3550
  const lineGap = options.lineGap || this._lineGap || 0;
@@ -3725,28 +3747,42 @@ var TextMixin = {
3725
3747
  }
3726
3748
  };
3727
3749
 
3750
+ const toBinaryString = bytes => {
3751
+ const chunkSize = 0x8000;
3752
+ let out = '';
3753
+ for (let i = 0; i < bytes.length; i += chunkSize) {
3754
+ const end = Math.min(i + chunkSize, bytes.length);
3755
+ out += String.fromCharCode.apply(null, bytes.subarray(i, end));
3756
+ }
3757
+ return out;
3758
+ };
3759
+ const readUInt16BE = (bytes, offset = 0) => (bytes[offset] << 8 | bytes[offset + 1]) >>> 0;
3760
+ const readUInt16LE = (bytes, offset = 0) => (bytes[offset + 1] << 8 | bytes[offset]) >>> 0;
3761
+ const readUInt32BE = (bytes, offset = 0) => bytes[offset] * 0x1000000 + (bytes[offset + 1] << 16 | bytes[offset + 2] << 8 | bytes[offset + 3]) >>> 0;
3762
+ const readUInt32LE = (bytes, offset = 0) => (bytes[offset] | bytes[offset + 1] << 8 | bytes[offset + 2] << 16) + bytes[offset + 3] * 0x1000000 >>> 0;
3763
+
3728
3764
  const parseExifOrientation = data => {
3729
3765
  if (!data || data.length < 20) return null;
3730
3766
  let pos = 2;
3731
3767
  while (pos < data.length - 4) {
3732
3768
  while (pos < data.length && data[pos] !== 0xff) pos++;
3733
3769
  if (pos >= data.length - 4) return null;
3734
- const marker = data.readUInt16BE(pos);
3770
+ const marker = readUInt16BE(data, pos);
3735
3771
  pos += 2;
3736
3772
  if (marker === 0xffda) return null;
3737
3773
  if (marker >= 0xffd0 && marker <= 0xffd9 || marker === 0xff01) continue;
3738
3774
  if (pos + 2 > data.length) return null;
3739
- const segmentLength = data.readUInt16BE(pos);
3775
+ const segmentLength = readUInt16BE(data, pos);
3740
3776
  if (marker === 0xffe1 && pos + 8 <= data.length) {
3741
- const exifHeader = data.subarray(pos + 2, pos + 8).toString('binary');
3777
+ const exifHeader = toBinaryString(data.subarray(pos + 2, pos + 8));
3742
3778
  if (exifHeader === 'Exif\x00\x00') {
3743
3779
  const tiffStart = pos + 8;
3744
3780
  if (tiffStart + 8 > data.length) return null;
3745
- const byteOrder = data.subarray(tiffStart, tiffStart + 2).toString('ascii');
3781
+ const byteOrder = toBinaryString(data.subarray(tiffStart, tiffStart + 2));
3746
3782
  const isLittleEndian = byteOrder === 'II';
3747
3783
  if (!isLittleEndian && byteOrder !== 'MM') return null;
3748
- const read16 = isLittleEndian ? o => data.readUInt16LE(o) : o => data.readUInt16BE(o);
3749
- const read32 = isLittleEndian ? o => data.readUInt32LE(o) : o => data.readUInt32BE(o);
3784
+ const read16 = isLittleEndian ? o => readUInt16LE(data, o) : o => readUInt16BE(data, o);
3785
+ const read32 = isLittleEndian ? o => readUInt32LE(data, o) : o => readUInt32BE(data, o);
3750
3786
  if (read16(tiffStart + 2) !== 42) return null;
3751
3787
  const ifdPos = tiffStart + read32(tiffStart + 4);
3752
3788
  if (ifdPos + 2 > data.length) return null;
@@ -3801,7 +3837,7 @@ class JPEG {
3801
3837
  pos += 2;
3802
3838
  this.width = this.data.readUInt16BE(pos);
3803
3839
  pos += 2;
3804
- const channels = this.data[pos++];
3840
+ const channels = this.data[pos + 1];
3805
3841
  this.colorSpace = COLOR_SPACE_MAP[channels];
3806
3842
  this.obj = null;
3807
3843
  }
@@ -3836,58 +3872,60 @@ class PNGImage {
3836
3872
  this.obj = null;
3837
3873
  }
3838
3874
  embed(document) {
3839
- let dataDecoded = false;
3840
3875
  this.document = document;
3841
3876
  if (this.obj) {
3842
3877
  return;
3843
3878
  }
3844
- const hasAlphaChannel = this.image.hasAlphaChannel;
3845
- const isInterlaced = this.image.interlaceMethod === 1;
3846
- this.obj = this.document.ref({
3879
+ const {
3880
+ image,
3881
+ height,
3882
+ width
3883
+ } = this;
3884
+ const hasAlphaChannel = image.hasAlphaChannel;
3885
+ const isInterlaced = image.interlaceMethod === 1;
3886
+ const obj = this.obj = document.ref({
3847
3887
  Type: 'XObject',
3848
3888
  Subtype: 'Image',
3849
- BitsPerComponent: hasAlphaChannel ? 8 : this.image.bits,
3850
- Width: this.width,
3851
- Height: this.height,
3889
+ BitsPerComponent: hasAlphaChannel ? 8 : image.bits,
3890
+ Width: width,
3891
+ Height: height,
3852
3892
  Filter: 'FlateDecode'
3853
3893
  });
3854
3894
  if (!hasAlphaChannel) {
3855
- const params = this.document.ref({
3895
+ const params = document.ref({
3856
3896
  Predictor: isInterlaced ? 1 : 15,
3857
- Colors: this.image.colors,
3858
- BitsPerComponent: this.image.bits,
3859
- Columns: this.width
3897
+ Colors: image.colors,
3898
+ BitsPerComponent: image.bits,
3899
+ Columns: width
3860
3900
  });
3861
- this.obj.data['DecodeParms'] = params;
3901
+ obj.data['DecodeParms'] = params;
3862
3902
  params.end();
3863
3903
  }
3864
- if (this.image.palette.length === 0) {
3865
- this.obj.data['ColorSpace'] = this.image.colorSpace;
3904
+ if (image.palette.length === 0) {
3905
+ obj.data['ColorSpace'] = image.colorSpace;
3866
3906
  } else {
3867
- const palette = this.document.ref();
3868
- palette.end(Buffer.from(this.image.palette));
3869
- this.obj.data['ColorSpace'] = ['Indexed', 'DeviceRGB', this.image.palette.length / 3 - 1, palette];
3870
- }
3871
- if (this.image.transparency.grayscale != null) {
3872
- const val = this.image.transparency.grayscale;
3873
- this.obj.data['Mask'] = [val, val];
3874
- } else if (this.image.transparency.rgb) {
3907
+ const palette = document.ref();
3908
+ palette.end(Buffer.from(image.palette));
3909
+ obj.data['ColorSpace'] = ['Indexed', 'DeviceRGB', image.palette.length / 3 - 1, palette];
3910
+ }
3911
+ if (image.transparency.grayscale != null) {
3912
+ const val = image.transparency.grayscale;
3913
+ obj.data['Mask'] = [val, val];
3914
+ } else if (image.transparency.rgb) {
3875
3915
  const {
3876
3916
  rgb
3877
- } = this.image.transparency;
3917
+ } = image.transparency;
3878
3918
  const mask = [];
3879
3919
  for (let x of rgb) {
3880
3920
  mask.push(x, x);
3881
3921
  }
3882
- this.obj.data['Mask'] = mask;
3883
- } else if (this.image.transparency.indexed) {
3884
- dataDecoded = true;
3922
+ obj.data['Mask'] = mask;
3923
+ } else if (image.transparency.indexed) {
3885
3924
  return this.loadIndexedAlphaChannel();
3886
3925
  } else if (hasAlphaChannel) {
3887
- dataDecoded = true;
3888
3926
  return this.splitAlphaChannel();
3889
3927
  }
3890
- if (isInterlaced && !dataDecoded) {
3928
+ if (isInterlaced && true) {
3891
3929
  return this.decodeData();
3892
3930
  }
3893
3931
  this.finalize();
@@ -3978,7 +4016,7 @@ class PDFImage {
3978
4016
  }
3979
4017
  if (data[0] === 0xff && data[1] === 0xd8) {
3980
4018
  return new JPEG(data, label);
3981
- } else if (data[0] === 0x89 && data.toString('ascii', 1, 4) === 'PNG') {
4019
+ } else if (data[0] === 0x89 && data[1] === 0x50 && data[2] === 0x4e && data[3] === 0x47) {
3982
4020
  return new PNGImage(data, label);
3983
4021
  } else {
3984
4022
  throw new Error('Unknown image format.');
@@ -3991,8 +4029,7 @@ var ImagesMixin = {
3991
4029
  this._imageRegistry = {};
3992
4030
  this._imageCount = 0;
3993
4031
  },
3994
- image(src, x, y) {
3995
- let options = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {};
4032
+ image(src, x, y, options = {}) {
3996
4033
  let bh, bp, bw, image, ip, left, left1, originX, originY;
3997
4034
  if (typeof x === 'object') {
3998
4035
  options = x;
@@ -4150,6 +4187,9 @@ var ImagesMixin = {
4150
4187
  this.y += h;
4151
4188
  }
4152
4189
  this.save();
4190
+ if (options.opacity != null) {
4191
+ this._doOpacity(options.opacity, null);
4192
+ }
4153
4193
  if (rotateAngle) {
4154
4194
  this.rotate(rotateAngle, {
4155
4195
  origin: [originX, originY]
@@ -4213,8 +4253,7 @@ var AnnotationsMixin = {
4213
4253
  ref.end();
4214
4254
  return this;
4215
4255
  },
4216
- note(x, y, w, h, contents) {
4217
- let options = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : {};
4256
+ note(x, y, w, h, contents, options = {}) {
4218
4257
  options.Subtype = 'Text';
4219
4258
  options.Contents = new String(contents);
4220
4259
  if (options.Name == null) {
@@ -4225,8 +4264,7 @@ var AnnotationsMixin = {
4225
4264
  }
4226
4265
  return this.annotate(x, y, w, h, options);
4227
4266
  },
4228
- goTo(x, y, w, h, name) {
4229
- let options = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : {};
4267
+ goTo(x, y, w, h, name, options = {}) {
4230
4268
  options.Subtype = 'Link';
4231
4269
  options.A = this.ref({
4232
4270
  S: 'GoTo',
@@ -4235,8 +4273,7 @@ var AnnotationsMixin = {
4235
4273
  options.A.end();
4236
4274
  return this.annotate(x, y, w, h, options);
4237
4275
  },
4238
- link(x, y, w, h, url) {
4239
- let options = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : {};
4276
+ link(x, y, w, h, url, options = {}) {
4240
4277
  options.Subtype = 'Link';
4241
4278
  if (typeof url === 'number') {
4242
4279
  const pages = this._root.data.Pages.data;
@@ -4261,60 +4298,50 @@ var AnnotationsMixin = {
4261
4298
  }
4262
4299
  return this.annotate(x, y, w, h, options);
4263
4300
  },
4264
- _markup(x, y, w, h) {
4265
- let options = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : {};
4301
+ _markup(x, y, w, h, options = {}) {
4266
4302
  const [x1, y1, x2, y2] = this._convertRect(x, y, w, h);
4267
4303
  options.QuadPoints = [x1, y2, x2, y2, x1, y1, x2, y1];
4268
4304
  options.Contents = new String();
4269
4305
  return this.annotate(x, y, w, h, options);
4270
4306
  },
4271
- highlight(x, y, w, h) {
4272
- let options = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : {};
4307
+ highlight(x, y, w, h, options = {}) {
4273
4308
  options.Subtype = 'Highlight';
4274
4309
  if (options.color == null) {
4275
4310
  options.color = [241, 238, 148];
4276
4311
  }
4277
4312
  return this._markup(x, y, w, h, options);
4278
4313
  },
4279
- underline(x, y, w, h) {
4280
- let options = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : {};
4314
+ underline(x, y, w, h, options = {}) {
4281
4315
  options.Subtype = 'Underline';
4282
4316
  return this._markup(x, y, w, h, options);
4283
4317
  },
4284
- strike(x, y, w, h) {
4285
- let options = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : {};
4318
+ strike(x, y, w, h, options = {}) {
4286
4319
  options.Subtype = 'StrikeOut';
4287
4320
  return this._markup(x, y, w, h, options);
4288
4321
  },
4289
- lineAnnotation(x1, y1, x2, y2) {
4290
- let options = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : {};
4322
+ lineAnnotation(x1, y1, x2, y2, options = {}) {
4291
4323
  options.Subtype = 'Line';
4292
4324
  options.Contents = new String();
4293
4325
  options.L = [x1, this.page.height - y1, x2, this.page.height - y2];
4294
4326
  return this.annotate(x1, y1, x2, y2, options);
4295
4327
  },
4296
- rectAnnotation(x, y, w, h) {
4297
- let options = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : {};
4328
+ rectAnnotation(x, y, w, h, options = {}) {
4298
4329
  options.Subtype = 'Square';
4299
4330
  options.Contents = new String();
4300
4331
  return this.annotate(x, y, w, h, options);
4301
4332
  },
4302
- ellipseAnnotation(x, y, w, h) {
4303
- let options = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : {};
4333
+ ellipseAnnotation(x, y, w, h, options = {}) {
4304
4334
  options.Subtype = 'Circle';
4305
4335
  options.Contents = new String();
4306
4336
  return this.annotate(x, y, w, h, options);
4307
4337
  },
4308
- textAnnotation(x, y, w, h, text) {
4309
- let options = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : {};
4338
+ textAnnotation(x, y, w, h, text, options = {}) {
4310
4339
  options.Subtype = 'FreeText';
4311
4340
  options.Contents = new String(text);
4312
4341
  options.DA = new String();
4313
4342
  return this.annotate(x, y, w, h, options);
4314
4343
  },
4315
- fileAnnotation(x, y, w, h) {
4316
- let file = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : {};
4317
- let options = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : {};
4344
+ fileAnnotation(x, y, w, h, file = {}, options = {}) {
4318
4345
  const filespec = this.file(file.src, Object.assign({
4319
4346
  hidden: true
4320
4347
  }, file));
@@ -4349,8 +4376,7 @@ const DEFAULT_OPTIONS = {
4349
4376
  expanded: false
4350
4377
  };
4351
4378
  class PDFOutline {
4352
- constructor(document, parent, title, dest) {
4353
- let options = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : DEFAULT_OPTIONS;
4379
+ constructor(document, parent, title, dest, options = DEFAULT_OPTIONS) {
4354
4380
  this.document = document;
4355
4381
  this.options = options;
4356
4382
  this.outlineData = {};
@@ -4371,8 +4397,7 @@ class PDFOutline {
4371
4397
  this.dictionary = this.document.ref(this.outlineData);
4372
4398
  this.children = [];
4373
4399
  }
4374
- addItem(title) {
4375
- let options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : DEFAULT_OPTIONS;
4400
+ addItem(title, options = DEFAULT_OPTIONS) {
4376
4401
  const pages = this.document._root.data.Pages.data.Kids;
4377
4402
  const dest = options.pageNumber != null ? pages[options.pageNumber] : this.document.page.dictionary;
4378
4403
  const result = new PDFOutline(this.document, this.dictionary, title, dest, options);
@@ -4429,9 +4454,7 @@ class PDFStructureContent {
4429
4454
  }
4430
4455
 
4431
4456
  class PDFStructureElement {
4432
- constructor(document, type) {
4433
- let options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
4434
- let children = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : null;
4457
+ constructor(document, type, options = {}, children = null) {
4435
4458
  this.document = document;
4436
4459
  this._attached = false;
4437
4460
  this._ended = false;
@@ -4444,21 +4467,41 @@ class PDFStructureElement {
4444
4467
  children = options;
4445
4468
  options = {};
4446
4469
  }
4447
- if (typeof options.title !== 'undefined') {
4470
+ if (options.title) {
4448
4471
  data.T = new String(options.title);
4449
4472
  }
4450
- if (typeof options.lang !== 'undefined') {
4473
+ if (options.lang) {
4451
4474
  data.Lang = new String(options.lang);
4452
4475
  }
4453
- if (typeof options.alt !== 'undefined') {
4476
+ if (options.alt) {
4454
4477
  data.Alt = new String(options.alt);
4455
4478
  }
4456
- if (typeof options.expanded !== 'undefined') {
4479
+ if (options.expanded) {
4457
4480
  data.E = new String(options.expanded);
4458
4481
  }
4459
- if (typeof options.actual !== 'undefined') {
4482
+ if (options.actual) {
4460
4483
  data.ActualText = new String(options.actual);
4461
4484
  }
4485
+ const hasBbox = Array.isArray(options.bbox) && options.bbox.length === 4;
4486
+ const hasPlacement = typeof options.placement === 'string';
4487
+ if (hasBbox || hasPlacement) {
4488
+ const attrs = {
4489
+ O: 'Layout'
4490
+ };
4491
+ attrs.Placement = hasPlacement ? options.placement : 'Block';
4492
+ if (hasBbox) {
4493
+ const height = document.page.height;
4494
+ attrs.BBox = [options.bbox[0], height - options.bbox[3], options.bbox[2], height - options.bbox[1]];
4495
+ }
4496
+ data.A = attrs;
4497
+ }
4498
+ if (options.scope) {
4499
+ data.A = {
4500
+ ...(data.A || {}),
4501
+ O: 'Table',
4502
+ Scope: options.scope
4503
+ };
4504
+ }
4462
4505
  this._children = [];
4463
4506
  if (children) {
4464
4507
  if (!Array.isArray(children)) {
@@ -4494,11 +4537,10 @@ class PDFStructureElement {
4494
4537
  return this;
4495
4538
  }
4496
4539
  _addContentToParentTree(content) {
4497
- content.refs.forEach(_ref => {
4498
- let {
4499
- pageRef,
4500
- mcid
4501
- } = _ref;
4540
+ content.refs.forEach(({
4541
+ pageRef,
4542
+ mcid
4543
+ }) => {
4502
4544
  const pageStructParents = this.document.getStructParentTree().get(pageRef.data.StructParents);
4503
4545
  pageStructParents[mcid] = this.dictionary;
4504
4546
  });
@@ -4585,11 +4627,10 @@ class PDFStructureElement {
4585
4627
  this.dictionary.data.K.push(child.dictionary);
4586
4628
  }
4587
4629
  if (child instanceof PDFStructureContent) {
4588
- child.refs.forEach(_ref2 => {
4589
- let {
4590
- pageRef,
4591
- mcid
4592
- } = _ref2;
4630
+ child.refs.forEach(({
4631
+ pageRef,
4632
+ mcid
4633
+ }) => {
4593
4634
  if (!this.dictionary.data.Pg) {
4594
4635
  this.dictionary.data.Pg = pageRef;
4595
4636
  }
@@ -4636,8 +4677,7 @@ var MarkingsMixin = {
4636
4677
  this.getStructTreeRoot();
4637
4678
  }
4638
4679
  },
4639
- markContent(tag) {
4640
- let options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null;
4680
+ markContent(tag, options = null) {
4641
4681
  if (tag === 'Artifact' || options && options.mcid) {
4642
4682
  let toClose = 0;
4643
4683
  this.page.markings.forEach(marking => {
@@ -4692,8 +4732,7 @@ var MarkingsMixin = {
4692
4732
  this.addContent(`/${tag} ${PDFObject.convert(dictionary)} BDC`);
4693
4733
  return this;
4694
4734
  },
4695
- markStructureContent(tag) {
4696
- let options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
4735
+ markStructureContent(tag, options = {}) {
4697
4736
  const pageStructParents = this.getStructParentTree().get(this.page.structParentTreeKey);
4698
4737
  const mcid = pageStructParents.length;
4699
4738
  pageStructParents.push(null);
@@ -4717,9 +4756,7 @@ var MarkingsMixin = {
4717
4756
  }
4718
4757
  return this;
4719
4758
  },
4720
- struct(type) {
4721
- let options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
4722
- let children = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null;
4759
+ struct(type, options = {}, children = null) {
4723
4760
  return new PDFStructureElement(this, type, options, children);
4724
4761
  },
4725
4762
  addStructure(structElem) {
@@ -4884,15 +4921,13 @@ var AcroFormMixin = {
4884
4921
  }
4885
4922
  return this;
4886
4923
  },
4887
- formField(name) {
4888
- let options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
4924
+ formField(name, options = {}) {
4889
4925
  let fieldDict = this._fieldDict(name, null, options);
4890
4926
  let fieldRef = this.ref(fieldDict);
4891
4927
  this._addToParent(fieldRef);
4892
4928
  return fieldRef;
4893
4929
  },
4894
- formAnnotation(name, type, x, y, w, h) {
4895
- let options = arguments.length > 6 && arguments[6] !== undefined ? arguments[6] : {};
4930
+ formAnnotation(name, type, x, y, w, h, options = {}) {
4896
4931
  let fieldDict = this._fieldDict(name, type, options);
4897
4932
  fieldDict.Subtype = 'Widget';
4898
4933
  if (fieldDict.F === undefined) {
@@ -4902,28 +4937,22 @@ var AcroFormMixin = {
4902
4937
  let annotRef = this.page.annotations[this.page.annotations.length - 1];
4903
4938
  return this._addToParent(annotRef);
4904
4939
  },
4905
- formText(name, x, y, w, h) {
4906
- let options = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : {};
4940
+ formText(name, x, y, w, h, options = {}) {
4907
4941
  return this.formAnnotation(name, 'text', x, y, w, h, options);
4908
4942
  },
4909
- formPushButton(name, x, y, w, h) {
4910
- let options = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : {};
4943
+ formPushButton(name, x, y, w, h, options = {}) {
4911
4944
  return this.formAnnotation(name, 'pushButton', x, y, w, h, options);
4912
4945
  },
4913
- formCombo(name, x, y, w, h) {
4914
- let options = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : {};
4946
+ formCombo(name, x, y, w, h, options = {}) {
4915
4947
  return this.formAnnotation(name, 'combo', x, y, w, h, options);
4916
4948
  },
4917
- formList(name, x, y, w, h) {
4918
- let options = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : {};
4949
+ formList(name, x, y, w, h, options = {}) {
4919
4950
  return this.formAnnotation(name, 'list', x, y, w, h, options);
4920
4951
  },
4921
- formRadioButton(name, x, y, w, h) {
4922
- let options = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : {};
4952
+ formRadioButton(name, x, y, w, h, options = {}) {
4923
4953
  return this.formAnnotation(name, 'radioButton', x, y, w, h, options);
4924
4954
  },
4925
- formCheckbox(name, x, y, w, h) {
4926
- let options = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : {};
4955
+ formCheckbox(name, x, y, w, h, options = {}) {
4927
4956
  return this.formAnnotation(name, 'checkbox', x, y, w, h, options);
4928
4957
  },
4929
4958
  _addToParent(fieldRef) {
@@ -4938,8 +4967,7 @@ var AcroFormMixin = {
4938
4967
  }
4939
4968
  return this;
4940
4969
  },
4941
- _fieldDict(name, type) {
4942
- let options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
4970
+ _fieldDict(name, type, options = {}) {
4943
4971
  if (!this._acroform) {
4944
4972
  throw new Error('Call document.initForm() method before adding form elements to document');
4945
4973
  }
@@ -5128,8 +5156,7 @@ var AcroFormMixin = {
5128
5156
  };
5129
5157
 
5130
5158
  var AttachmentsMixin = {
5131
- file(src) {
5132
- let options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
5159
+ file(src, options = {}) {
5133
5160
  options.name = options.name || src;
5134
5161
  options.relationship = options.relationship || 'Unspecified';
5135
5162
  const refBody = {
@@ -5148,7 +5175,7 @@ var AttachmentsMixin = {
5148
5175
  const match = /^data:(.*?);base64,(.*)$/.exec(src);
5149
5176
  if (match) {
5150
5177
  if (match[1]) {
5151
- refBody.Subtype = match[1].replace('/', '#2F');
5178
+ refBody.Subtype = escapeName(match[1]);
5152
5179
  }
5153
5180
  data = Buffer.from(match[2], 'base64');
5154
5181
  } else {
@@ -5171,7 +5198,7 @@ var AttachmentsMixin = {
5171
5198
  refBody.Params.ModDate = options.modifiedDate;
5172
5199
  }
5173
5200
  if (options.type) {
5174
- refBody.Subtype = options.type.replace('/', '#2F');
5201
+ refBody.Subtype = escapeName(options.type);
5175
5202
  }
5176
5203
  const checksum = md5Hex(new Uint8Array(data));
5177
5204
  refBody.Params.CheckSum = new String(checksum);
@@ -5312,10 +5339,10 @@ const ROW_FIELDS = ['height', 'minHeight', 'maxHeight'];
5312
5339
  const COLUMN_FIELDS = ['width', 'minWidth', 'maxWidth'];
5313
5340
  function memoize(fn, maxSize) {
5314
5341
  const cache = new Map();
5315
- return function () {
5316
- const key = arguments.length <= 0 ? undefined : arguments[0];
5342
+ return function (...args) {
5343
+ const key = args[0];
5317
5344
  if (!cache.has(key)) {
5318
- cache.set(key, fn(...arguments));
5345
+ cache.set(key, fn(...args));
5319
5346
  if (cache.size > maxSize) cache.delete(cache.keys().next());
5320
5347
  }
5321
5348
  return cache.get(key);
@@ -5324,12 +5351,9 @@ function memoize(fn, maxSize) {
5324
5351
  function isObject(item) {
5325
5352
  return item && typeof item === 'object' && !Array.isArray(item);
5326
5353
  }
5327
- function deepMerge(target) {
5354
+ function deepMerge(target, ...sources) {
5328
5355
  if (!isObject(target)) return target;
5329
5356
  target = deepClone(target);
5330
- for (var _len = arguments.length, sources = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
5331
- sources[_key - 1] = arguments[_key];
5332
- }
5333
5357
  for (const source of sources) {
5334
5358
  if (isObject(source)) {
5335
5359
  for (const key in source) {
@@ -5358,14 +5382,8 @@ function normalizedDefaultStyle(defaultStyleInternal) {
5358
5382
  if (typeof defaultStyle !== 'object') defaultStyle = {
5359
5383
  text: defaultStyle
5360
5384
  };
5361
- const defaultRowStyle = Object.fromEntries(Object.entries(defaultStyle).filter(_ref => {
5362
- let [k] = _ref;
5363
- return ROW_FIELDS.includes(k);
5364
- }));
5365
- const defaultColStyle = Object.fromEntries(Object.entries(defaultStyle).filter(_ref2 => {
5366
- let [k] = _ref2;
5367
- return COLUMN_FIELDS.includes(k);
5368
- }));
5385
+ const defaultRowStyle = Object.fromEntries(Object.entries(defaultStyle).filter(([k]) => ROW_FIELDS.includes(k)));
5386
+ const defaultColStyle = Object.fromEntries(Object.entries(defaultStyle).filter(([k]) => COLUMN_FIELDS.includes(k)));
5369
5387
  defaultStyle.padding = normalizeSides(defaultStyle.padding);
5370
5388
  defaultStyle.border = normalizeSides(defaultStyle.border);
5371
5389
  defaultStyle.borderColor = normalizeSides(defaultStyle.borderColor);
@@ -5882,10 +5900,7 @@ function renderCellText(cell) {
5882
5900
  if (cell.font) doc.font(rollbackFont, rollbackFontFamily, rollbackFontSize);
5883
5901
  }
5884
5902
  function renderBorder(border, borderColor, x, y, width, height, mask) {
5885
- border = Object.fromEntries(Object.entries(border).map(_ref => {
5886
- let [k, v] = _ref;
5887
- return [k, mask && !mask[k] ? 0 : v];
5888
- }));
5903
+ border = Object.fromEntries(Object.entries(border).map(([k, v]) => [k, mask && !mask[k] ? 0 : v]));
5889
5904
  const doc = this.document;
5890
5905
  if ([border.right, border.bottom, border.left].every(val => val === border.top)) {
5891
5906
  if (border.top > 0) {
@@ -5908,8 +5923,7 @@ function renderBorder(border, borderColor, x, y, width, height, mask) {
5908
5923
  }
5909
5924
 
5910
5925
  class PDFTable {
5911
- constructor(document) {
5912
- let opts = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
5926
+ constructor(document, opts = {}) {
5913
5927
  this.document = document;
5914
5928
  this.opts = Object.freeze(opts);
5915
5929
  normalizeTable.call(this);
@@ -5921,8 +5935,7 @@ class PDFTable {
5921
5935
  return this.end();
5922
5936
  }
5923
5937
  }
5924
- row(row) {
5925
- let lastRow = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
5938
+ row(row, lastRow = false) {
5926
5939
  if (this._ended) {
5927
5940
  throw new Error(`Table was marked as ended on row ${this._currRowIndex}`);
5928
5941
  }
@@ -5973,8 +5986,7 @@ class PDFMetadata {
5973
5986
  <?xpacket end="w"?>
5974
5987
  `);
5975
5988
  }
5976
- append(xml) {
5977
- let newline = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
5989
+ append(xml, newline = true) {
5978
5990
  this._metadata = this._metadata.concat(xml);
5979
5991
  if (newline) this._metadata = this._metadata.concat('\n');
5980
5992
  }
@@ -5994,8 +6006,7 @@ var MetadataMixin = {
5994
6006
  initMetadata() {
5995
6007
  this.metadata = new PDFMetadata();
5996
6008
  },
5997
- appendXML(xml) {
5998
- let newline = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
6009
+ appendXML(xml, newline = true) {
5999
6010
  this.metadata.append(xml, newline);
6000
6011
  },
6001
6012
  _addInfo() {
@@ -6042,7 +6053,7 @@ var MetadataMixin = {
6042
6053
  }
6043
6054
  this.appendXML(`
6044
6055
  <rdf:Description rdf:about="" xmlns:pdf="http://ns.adobe.com/pdf/1.3/">
6045
- <pdf:Producer>${this.info.Creator}</pdf:Producer>`, false);
6056
+ <pdf:Producer>${this.info.Producer}</pdf:Producer>`, false);
6046
6057
  if (this.info.Keywords) {
6047
6058
  this.appendXML(`
6048
6059
  <pdf:Keywords>${this.info.Keywords}</pdf:Keywords>`, false);
@@ -6069,8 +6080,7 @@ var MetadataMixin = {
6069
6080
  };
6070
6081
 
6071
6082
  class PDFDocument extends stream.Readable {
6072
- constructor() {
6073
- let options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
6083
+ constructor(options = {}) {
6074
6084
  super(options);
6075
6085
  this.options = options;
6076
6086
  switch (options.pdfVersion) {
@@ -6202,10 +6212,7 @@ class PDFDocument extends stream.Readable {
6202
6212
  page.end();
6203
6213
  }
6204
6214
  }
6205
- addNamedDestination(name) {
6206
- for (var _len = arguments.length, args = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
6207
- args[_key - 1] = arguments[_key];
6208
- }
6215
+ addNamedDestination(name, ...args) {
6209
6216
  if (args.length === 0) {
6210
6217
  args = ['XYZ', null, null, null];
6211
6218
  }