pdfkit 0.13.0 → 0.15.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.
@@ -5,6 +5,7 @@ import CryptoJS from 'crypto-js';
5
5
  import fontkit from 'fontkit';
6
6
  import { EventEmitter } from 'events';
7
7
  import LineBreaker from 'linebreak';
8
+ import exif from 'jpeg-exif';
8
9
  import PNG from 'png-js';
9
10
 
10
11
  /*
@@ -59,7 +60,9 @@ class PDFTree {
59
60
  return out.join('\n');
60
61
  }
61
62
 
62
- _compareKeys() {
63
+ _compareKeys()
64
+ /*a, b*/
65
+ {
63
66
  throw new Error('Must be implemented by subclasses');
64
67
  }
65
68
 
@@ -67,7 +70,9 @@ class PDFTree {
67
70
  throw new Error('Must be implemented by subclasses');
68
71
  }
69
72
 
70
- _dataForKey() {
73
+ _dataForKey()
74
+ /*k*/
75
+ {
71
76
  throw new Error('Must be implemented by subclasses');
72
77
  }
73
78
 
@@ -2668,6 +2673,11 @@ var VectorMixin = {
2668
2673
 
2669
2674
  transform(m11, m12, m21, m22, dx, dy) {
2670
2675
  // keep track of the current transformation matrix
2676
+ if (m11 === 1 && m12 === 0 && m21 === 0 && m22 === 1 && dx === 0 && dy === 0) {
2677
+ // Ignore identity transforms
2678
+ return this;
2679
+ }
2680
+
2671
2681
  var m = this._ctm;
2672
2682
  var [m0, m1, m2, m3, m4, m5] = m;
2673
2683
  m[0] = m0 * m11 + m2 * m12;
@@ -3237,6 +3247,14 @@ class EmbeddedFont extends PDFFont {
3237
3247
  descriptor.data.FontFile2 = fontFile;
3238
3248
  }
3239
3249
 
3250
+ if (this.document.subset) {
3251
+ var CIDSet = Buffer.from('FFFFFFFFC0', 'hex');
3252
+ var CIDSetRef = this.document.ref();
3253
+ CIDSetRef.write(CIDSet);
3254
+ CIDSetRef.end();
3255
+ descriptor.data.CIDSet = CIDSetRef;
3256
+ }
3257
+
3240
3258
  descriptor.end();
3241
3259
  var descendantFontData = {
3242
3260
  Type: 'Font',
@@ -3292,7 +3310,17 @@ class EmbeddedFont extends PDFFont {
3292
3310
  entries.push("<".concat(encoded.join(' '), ">"));
3293
3311
  }
3294
3312
 
3295
- cmap.end("/CIDInit /ProcSet findresource begin\n12 dict begin\nbegincmap\n/CIDSystemInfo <<\n /Registry (Adobe)\n /Ordering (UCS)\n /Supplement 0\n>> def\n/CMapName /Adobe-Identity-UCS def\n/CMapType 2 def\n1 begincodespacerange\n<0000><ffff>\nendcodespacerange\n1 beginbfrange\n<0000> <".concat(toHex(entries.length - 1), "> [").concat(entries.join(' '), "]\nendbfrange\nendcmap\nCMapName currentdict /CMap defineresource pop\nend\nend"));
3313
+ var chunkSize = 256;
3314
+ var chunks = Math.ceil(entries.length / chunkSize);
3315
+ var ranges = [];
3316
+
3317
+ for (var i = 0; i < chunks; i++) {
3318
+ var start = i * chunkSize;
3319
+ var end = Math.min((i + 1) * chunkSize, entries.length);
3320
+ ranges.push("<".concat(toHex(start), "> <").concat(toHex(end - 1), "> [").concat(entries.slice(start, end).join(' '), "]"));
3321
+ }
3322
+
3323
+ cmap.end("/CIDInit /ProcSet findresource begin\n12 dict begin\nbegincmap\n/CIDSystemInfo <<\n /Registry (Adobe)\n /Ordering (UCS)\n /Supplement 0\n>> def\n/CMapName /Adobe-Identity-UCS def\n/CMapType 2 def\n1 begincodespacerange\n<0000><ffff>\nendcodespacerange\n1 beginbfrange\n".concat(ranges.join('\n'), "\nendbfrange\nendcmap\nCMapName currentdict /CMap defineresource pop\nend\nend"));
3296
3324
  return cmap;
3297
3325
  }
3298
3326
 
@@ -3421,6 +3449,9 @@ var FontsMixin = {
3421
3449
 
3422
3450
  };
3423
3451
 
3452
+ var SOFT_HYPHEN = '\u00AD';
3453
+ var HYPHEN = '-';
3454
+
3424
3455
  class LineWrapper extends EventEmitter {
3425
3456
  constructor(document, options) {
3426
3457
  super();
@@ -3491,6 +3522,14 @@ class LineWrapper extends EventEmitter {
3491
3522
  return this.document.widthOfString(word, this) + this.characterSpacing + this.wordSpacing;
3492
3523
  }
3493
3524
 
3525
+ canFit(word, w) {
3526
+ if (word[word.length - 1] != SOFT_HYPHEN) {
3527
+ return w <= this.spaceLeft;
3528
+ }
3529
+
3530
+ return w + this.wordWidth(HYPHEN) <= this.spaceLeft;
3531
+ }
3532
+
3494
3533
  eachWord(text, fn) {
3495
3534
  // setup a unicode line breaker
3496
3535
  var bk;
@@ -3621,13 +3660,13 @@ class LineWrapper extends EventEmitter {
3621
3660
  this.spaceLeft = this.lineWidth;
3622
3661
  }
3623
3662
 
3624
- if (w <= this.spaceLeft) {
3663
+ if (this.canFit(word, w)) {
3625
3664
  buffer += word;
3626
3665
  textWidth += w;
3627
3666
  wc++;
3628
3667
  }
3629
3668
 
3630
- if (bk.required || w > this.spaceLeft) {
3669
+ if (bk.required || !this.canFit(word, w)) {
3631
3670
  // if the user specified a max height and an ellipsis, and is about to pass the
3632
3671
  // max height and max columns after the next line, append the ellipsis
3633
3672
  var lh = this.document.currentLineHeight(true);
@@ -3664,6 +3703,12 @@ class LineWrapper extends EventEmitter {
3664
3703
  }
3665
3704
 
3666
3705
  this.emit('lastLine', options, this);
3706
+ } // Previous entry is a soft hyphen - add visible hyphen.
3707
+
3708
+
3709
+ if (buffer[buffer.length - 1] == SOFT_HYPHEN) {
3710
+ buffer = buffer.slice(0, -1) + HYPHEN;
3711
+ this.spaceLeft -= this.wordWidth(HYPHEN);
3667
3712
  }
3668
3713
 
3669
3714
  emitLine(); // if we've reached the edge of the page,
@@ -3869,8 +3914,8 @@ var TextMixin = {
3869
3914
  var flatten = function flatten(list) {
3870
3915
  var n = 1;
3871
3916
 
3872
- for (var _i = 0; _i < list.length; _i++) {
3873
- var item = list[_i];
3917
+ for (var i = 0; i < list.length; i++) {
3918
+ var item = list[i];
3874
3919
 
3875
3920
  if (Array.isArray(item)) {
3876
3921
  level++;
@@ -3902,75 +3947,82 @@ var TextMixin = {
3902
3947
  }
3903
3948
  };
3904
3949
 
3905
- wrapper = new LineWrapper(this, options);
3906
- wrapper.on('line', this._line);
3907
- level = 1;
3908
- var i = 0;
3909
- wrapper.on('firstLine', () => {
3910
- var item, itemType, labelType, bodyType;
3950
+ var drawListItem = function drawListItem(listItem) {
3951
+ wrapper = new LineWrapper(this, options);
3952
+ wrapper.on('line', this._line);
3953
+ level = 1;
3954
+ var i = 0;
3955
+ wrapper.once('firstLine', () => {
3956
+ var item, itemType, labelType, bodyType;
3911
3957
 
3912
- if (options.structParent) {
3913
- if (options.structTypes) {
3914
- [itemType, labelType, bodyType] = options.structTypes;
3915
- } else {
3916
- [itemType, labelType, bodyType] = ['LI', 'Lbl', 'LBody'];
3958
+ if (options.structParent) {
3959
+ if (options.structTypes) {
3960
+ [itemType, labelType, bodyType] = options.structTypes;
3961
+ } else {
3962
+ [itemType, labelType, bodyType] = ['LI', 'Lbl', 'LBody'];
3963
+ }
3917
3964
  }
3918
- }
3919
3965
 
3920
- if (itemType) {
3921
- item = this.struct(itemType);
3922
- options.structParent.add(item);
3923
- } else if (options.structParent) {
3924
- item = options.structParent;
3925
- }
3966
+ if (itemType) {
3967
+ item = this.struct(itemType);
3968
+ options.structParent.add(item);
3969
+ } else if (options.structParent) {
3970
+ item = options.structParent;
3971
+ }
3926
3972
 
3927
- var l;
3973
+ var l;
3928
3974
 
3929
- if ((l = levels[i++]) !== level) {
3930
- var diff = itemIndent * (l - level);
3931
- this.x += diff;
3932
- wrapper.lineWidth -= diff;
3933
- level = l;
3934
- }
3975
+ if ((l = levels[i++]) !== level) {
3976
+ var diff = itemIndent * (l - level);
3977
+ this.x += diff;
3978
+ wrapper.lineWidth -= diff;
3979
+ level = l;
3980
+ }
3935
3981
 
3936
- if (item && (labelType || bodyType)) {
3937
- item.add(this.struct(labelType || bodyType, [this.markStructureContent(labelType || bodyType)]));
3938
- }
3982
+ if (item && (labelType || bodyType)) {
3983
+ item.add(this.struct(labelType || bodyType, [this.markStructureContent(labelType || bodyType)]));
3984
+ }
3939
3985
 
3940
- switch (listType) {
3941
- case 'bullet':
3942
- this.circle(this.x - indent + r, this.y + midLine, r);
3943
- this.fill();
3944
- break;
3986
+ switch (listType) {
3987
+ case 'bullet':
3988
+ this.circle(this.x - indent + r, this.y + midLine, r);
3989
+ this.fill();
3990
+ break;
3945
3991
 
3946
- case 'numbered':
3947
- case 'lettered':
3948
- var text = label(numbers[i - 1]);
3992
+ case 'numbered':
3993
+ case 'lettered':
3994
+ var text = label(numbers[i - 1]);
3949
3995
 
3950
- this._fragment(text, this.x - indent, this.y, options);
3996
+ this._fragment(text, this.x - indent, this.y, options);
3951
3997
 
3952
- break;
3953
- }
3998
+ break;
3999
+ }
3954
4000
 
3955
- if (item && labelType && bodyType) {
3956
- item.add(this.struct(bodyType, [this.markStructureContent(bodyType)]));
3957
- }
4001
+ if (item && labelType && bodyType) {
4002
+ item.add(this.struct(bodyType, [this.markStructureContent(bodyType)]));
4003
+ }
4004
+
4005
+ if (item && item !== options.structParent) {
4006
+ item.end();
4007
+ }
4008
+ });
4009
+ wrapper.on('sectionStart', () => {
4010
+ var pos = indent + itemIndent * (level - 1);
4011
+ this.x += pos;
4012
+ return wrapper.lineWidth -= pos;
4013
+ });
4014
+ wrapper.on('sectionEnd', () => {
4015
+ var pos = indent + itemIndent * (level - 1);
4016
+ this.x -= pos;
4017
+ return wrapper.lineWidth += pos;
4018
+ });
4019
+ wrapper.wrap(listItem, options);
4020
+ };
4021
+
4022
+ for (var i = 0; i < items.length; i++) {
4023
+ drawListItem.call(this, items[i]);
4024
+ }
3958
4025
 
3959
- if (item && item !== options.structParent) {
3960
- item.end();
3961
- }
3962
- });
3963
- wrapper.on('sectionStart', () => {
3964
- var pos = indent + itemIndent * (level - 1);
3965
- this.x += pos;
3966
- return wrapper.lineWidth -= pos;
3967
- });
3968
- wrapper.on('sectionEnd', () => {
3969
- var pos = indent + itemIndent * (level - 1);
3970
- this.x -= pos;
3971
- return wrapper.lineWidth += pos;
3972
- });
3973
- wrapper.wrap(items.join('\n'), options);
3974
4026
  return this;
3975
4027
  },
3976
4028
 
@@ -4325,8 +4377,10 @@ class JPEG {
4325
4377
 
4326
4378
  if (this.data.readUInt16BE(0) !== 0xffd8) {
4327
4379
  throw 'SOI not found in JPEG';
4328
- }
4380
+ } // Parse the EXIF orientation
4381
+
4329
4382
 
4383
+ this.orientation = exif.fromBuffer(this.data).Orientation || 1;
4330
4384
  var pos = 2;
4331
4385
 
4332
4386
  while (pos < this.data.length) {
@@ -4564,7 +4618,7 @@ class PDFImage {
4564
4618
  } else {
4565
4619
  var match;
4566
4620
 
4567
- if (match = /^data:.+;base64,(.*)$/.exec(src)) {
4621
+ if (match = /^data:.+?;base64,(.*)$/.exec(src)) {
4568
4622
  data = Buffer.from(match[1], 'base64');
4569
4623
  } else {
4570
4624
  data = fs.readFileSync(src);
@@ -4594,13 +4648,15 @@ var ImagesMixin = {
4594
4648
 
4595
4649
  image(src, x, y) {
4596
4650
  var options = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {};
4597
- var bh, bp, bw, image, ip, left, left1;
4651
+ var bh, bp, bw, image, ip, left, left1, rotateAngle, originX, originY;
4598
4652
 
4599
4653
  if (typeof x === 'object') {
4600
4654
  options = x;
4601
4655
  x = null;
4602
- }
4656
+ } // Ignore orientation based on document options or image options
4657
+
4603
4658
 
4659
+ var ignoreOrientation = options.ignoreOrientation || options.ignoreOrientation !== false && this.options.ignoreOrientation;
4604
4660
  x = (left = x != null ? x : options.x) != null ? left : this.x;
4605
4661
  y = (left1 = y != null ? y : options.y) != null ? left1 : this.y;
4606
4662
 
@@ -4624,24 +4680,33 @@ var ImagesMixin = {
4624
4680
  this.page.xobjects[image.label] = image.obj;
4625
4681
  }
4626
4682
 
4627
- var w = options.width || image.width;
4628
- var h = options.height || image.height;
4683
+ var {
4684
+ width,
4685
+ height
4686
+ } = image; // If EXIF orientation calls for it, swap width and height
4687
+
4688
+ if (!ignoreOrientation && image.orientation > 4) {
4689
+ [width, height] = [height, width];
4690
+ }
4691
+
4692
+ var w = options.width || width;
4693
+ var h = options.height || height;
4629
4694
 
4630
4695
  if (options.width && !options.height) {
4631
- var wp = w / image.width;
4632
- w = image.width * wp;
4633
- h = image.height * wp;
4696
+ var wp = w / width;
4697
+ w = width * wp;
4698
+ h = height * wp;
4634
4699
  } else if (options.height && !options.width) {
4635
- var hp = h / image.height;
4636
- w = image.width * hp;
4637
- h = image.height * hp;
4700
+ var hp = h / height;
4701
+ w = width * hp;
4702
+ h = height * hp;
4638
4703
  } else if (options.scale) {
4639
- w = image.width * options.scale;
4640
- h = image.height * options.scale;
4704
+ w = width * options.scale;
4705
+ h = height * options.scale;
4641
4706
  } else if (options.fit) {
4642
4707
  [bw, bh] = options.fit;
4643
4708
  bp = bw / bh;
4644
- ip = image.width / image.height;
4709
+ ip = width / height;
4645
4710
 
4646
4711
  if (ip > bp) {
4647
4712
  w = bw;
@@ -4653,7 +4718,7 @@ var ImagesMixin = {
4653
4718
  } else if (options.cover) {
4654
4719
  [bw, bh] = options.cover;
4655
4720
  bp = bw / bh;
4656
- ip = image.width / image.height;
4721
+ ip = width / height;
4657
4722
 
4658
4723
  if (ip > bp) {
4659
4724
  h = bh;
@@ -4676,6 +4741,85 @@ var ImagesMixin = {
4676
4741
  } else if (options.valign === 'bottom') {
4677
4742
  y = y + bh - h;
4678
4743
  }
4744
+ }
4745
+
4746
+ if (!ignoreOrientation) {
4747
+ switch (image.orientation) {
4748
+ // No orientation (need to flip image, though, because of the default transform matrix on the document)
4749
+ default:
4750
+ case 1:
4751
+ h = -h;
4752
+ y -= h;
4753
+ rotateAngle = 0;
4754
+ break;
4755
+ // Flip Horizontal
4756
+
4757
+ case 2:
4758
+ w = -w;
4759
+ h = -h;
4760
+ x -= w;
4761
+ y -= h;
4762
+ rotateAngle = 0;
4763
+ break;
4764
+ // Rotate 180 degrees
4765
+
4766
+ case 3:
4767
+ originX = x;
4768
+ originY = y;
4769
+ h = -h;
4770
+ x -= w;
4771
+ rotateAngle = 180;
4772
+ break;
4773
+ // Flip vertical
4774
+
4775
+ case 4:
4776
+ // Do nothing, image will be flipped
4777
+ break;
4778
+ // Flip horizontally and rotate 270 degrees CW
4779
+
4780
+ case 5:
4781
+ originX = x;
4782
+ originY = y;
4783
+ [w, h] = [h, w];
4784
+ y -= h;
4785
+ rotateAngle = 90;
4786
+ break;
4787
+ // Rotate 90 degrees CW
4788
+
4789
+ case 6:
4790
+ originX = x;
4791
+ originY = y;
4792
+ [w, h] = [h, w];
4793
+ h = -h;
4794
+ rotateAngle = 90;
4795
+ break;
4796
+ // Flip horizontally and rotate 90 degrees CW
4797
+
4798
+ case 7:
4799
+ originX = x;
4800
+ originY = y;
4801
+ [w, h] = [h, w];
4802
+ h = -h;
4803
+ w = -w;
4804
+ x -= w;
4805
+ rotateAngle = 90;
4806
+ break;
4807
+ // Rotate 270 degrees CW
4808
+
4809
+ case 8:
4810
+ originX = x;
4811
+ originY = y;
4812
+ [w, h] = [h, w];
4813
+ h = -h;
4814
+ x -= w;
4815
+ y -= h;
4816
+ rotateAngle = -90;
4817
+ break;
4818
+ }
4819
+ } else {
4820
+ h = -h;
4821
+ y -= h;
4822
+ rotateAngle = 0;
4679
4823
  } // create link annotations if the link option is given
4680
4824
 
4681
4825
 
@@ -4697,7 +4841,14 @@ var ImagesMixin = {
4697
4841
  }
4698
4842
 
4699
4843
  this.save();
4700
- this.transform(w, 0, 0, -h, x, y + h);
4844
+
4845
+ if (rotateAngle) {
4846
+ this.rotate(rotateAngle, {
4847
+ origin: [originX, originY]
4848
+ });
4849
+ }
4850
+
4851
+ this.transform(w, 0, 0, h, x, y);
4701
4852
  this.addContent("/".concat(image.label, " Do"));
4702
4853
  this.restore();
4703
4854
  return this;
@@ -4991,18 +5142,29 @@ var OutlineMixin = {
4991
5142
 
4992
5143
  };
4993
5144
 
5145
+ function _defineProperty(obj, key, value) {
5146
+ if (key in obj) {
5147
+ Object.defineProperty(obj, key, {
5148
+ value: value,
5149
+ enumerable: true,
5150
+ configurable: true,
5151
+ writable: true
5152
+ });
5153
+ } else {
5154
+ obj[key] = value;
5155
+ }
5156
+
5157
+ return obj;
5158
+ }
5159
+
4994
5160
  function ownKeys(object, enumerableOnly) {
4995
5161
  var keys = Object.keys(object);
4996
5162
 
4997
5163
  if (Object.getOwnPropertySymbols) {
4998
5164
  var symbols = Object.getOwnPropertySymbols(object);
4999
-
5000
- if (enumerableOnly) {
5001
- symbols = symbols.filter(function (sym) {
5002
- return Object.getOwnPropertyDescriptor(object, sym).enumerable;
5003
- });
5004
- }
5005
-
5165
+ if (enumerableOnly) symbols = symbols.filter(function (sym) {
5166
+ return Object.getOwnPropertyDescriptor(object, sym).enumerable;
5167
+ });
5006
5168
  keys.push.apply(keys, symbols);
5007
5169
  }
5008
5170
 
@@ -5029,21 +5191,6 @@ function _objectSpread2(target) {
5029
5191
  return target;
5030
5192
  }
5031
5193
 
5032
- function _defineProperty(obj, key, value) {
5033
- if (key in obj) {
5034
- Object.defineProperty(obj, key, {
5035
- value: value,
5036
- enumerable: true,
5037
- configurable: true,
5038
- writable: true
5039
- });
5040
- } else {
5041
- obj[key] = value;
5042
- }
5043
-
5044
- return obj;
5045
- }
5046
-
5047
5194
  /*
5048
5195
  PDFStructureContent - a reference to a marked structure content
5049
5196
  By Ben Schmidt
@@ -5150,7 +5297,7 @@ class PDFStructureElement {
5150
5297
  }
5151
5298
 
5152
5299
  _addContentToParentTree(content) {
5153
- content.refs.forEach(_ref => {
5300
+ content.refs.forEach((_ref) => {
5154
5301
  var {
5155
5302
  pageRef,
5156
5303
  mcid
@@ -5258,7 +5405,7 @@ class PDFStructureElement {
5258
5405
  }
5259
5406
 
5260
5407
  if (child instanceof PDFStructureContent) {
5261
- child.refs.forEach(_ref2 => {
5408
+ child.refs.forEach((_ref2) => {
5262
5409
  var {
5263
5410
  pageRef,
5264
5411
  mcid
@@ -5819,7 +5966,10 @@ var AcroFormMixin = {
5819
5966
  var result = 0;
5820
5967
  Object.keys(options).forEach(key => {
5821
5968
  if (FIELD_FLAGS[key]) {
5822
- result |= FIELD_FLAGS[key];
5969
+ if (options[key]) {
5970
+ result |= FIELD_FLAGS[key];
5971
+ }
5972
+
5823
5973
  delete options[key];
5824
5974
  }
5825
5975
  });
@@ -5956,7 +6106,7 @@ var AttachmentsMixin = {
5956
6106
  } else {
5957
6107
  var match;
5958
6108
 
5959
- if (match = /^data:(.*);base64,(.*)$/.exec(src)) {
6109
+ if (match = /^data:(.*?);base64,(.*)$/.exec(src)) {
5960
6110
  if (match[1]) {
5961
6111
  refBody.Subtype = match[1].replace('/', '#2F');
5962
6112
  }
@@ -6044,6 +6194,201 @@ function isEqual(a, b) {
6044
6194
  return a.Subtype === b.Subtype && a.Params.CheckSum.toString() === b.Params.CheckSum.toString() && a.Params.Size === b.Params.Size && a.Params.CreationDate === b.Params.CreationDate && a.Params.ModDate === b.Params.ModDate;
6045
6195
  }
6046
6196
 
6197
+ var PDFA = {
6198
+ initPDFA(pSubset) {
6199
+ if (pSubset.charAt(pSubset.length - 3) === '-') {
6200
+ this.subset_conformance = pSubset.charAt(pSubset.length - 1).toUpperCase();
6201
+ this.subset = parseInt(pSubset.charAt(pSubset.length - 2));
6202
+ } else {
6203
+ // Default to Basic conformance when user doesn't specify
6204
+ this.subset_conformance = 'B';
6205
+ this.subset = parseInt(pSubset.charAt(pSubset.length - 1));
6206
+ }
6207
+ },
6208
+
6209
+ endSubset() {
6210
+ this._addPdfaMetadata();
6211
+
6212
+ var jsPath = "".concat(__dirname, "/data/sRGB_IEC61966_2_1.icc");
6213
+ var jestPath = "".concat(__dirname, "/../color_profiles/sRGB_IEC61966_2_1.icc");
6214
+
6215
+ this._addColorOutputIntent(fs.existsSync(jsPath) ? jsPath : jestPath);
6216
+ },
6217
+
6218
+ _addColorOutputIntent(pICCPath) {
6219
+ var iccProfile = fs.readFileSync(pICCPath);
6220
+ var colorProfileRef = this.ref({
6221
+ Length: iccProfile.length,
6222
+ N: 3
6223
+ });
6224
+ colorProfileRef.write(iccProfile);
6225
+ colorProfileRef.end();
6226
+ var intentRef = this.ref({
6227
+ Type: 'OutputIntent',
6228
+ S: 'GTS_PDFA1',
6229
+ Info: new String('sRGB IEC61966-2.1'),
6230
+ OutputConditionIdentifier: new String('sRGB IEC61966-2.1'),
6231
+ DestOutputProfile: colorProfileRef
6232
+ });
6233
+ intentRef.end();
6234
+ this._root.data.OutputIntents = [intentRef];
6235
+ },
6236
+
6237
+ _getPdfaid() {
6238
+ return "\n <rdf:Description xmlns:pdfaid=\"http://www.aiim.org/pdfa/ns/id/\" rdf:about=\"\">\n <pdfaid:part>".concat(this.subset, "</pdfaid:part>\n <pdfaid:conformance>").concat(this.subset_conformance, "</pdfaid:conformance>\n </rdf:Description>\n ");
6239
+ },
6240
+
6241
+ _addPdfaMetadata() {
6242
+ this.appendXML(this._getPdfaid());
6243
+ }
6244
+
6245
+ };
6246
+
6247
+ var PDFUA = {
6248
+ initPDFUA() {
6249
+ this.subset = 1;
6250
+ },
6251
+
6252
+ endSubset() {
6253
+ this._addPdfuaMetadata();
6254
+ },
6255
+
6256
+ _addPdfuaMetadata() {
6257
+ this.appendXML(this._getPdfuaid());
6258
+ },
6259
+
6260
+ _getPdfuaid() {
6261
+ return "\n <rdf:Description xmlns:pdfuaid=\"http://www.aiim.org/pdfua/ns/id/\" rdf:about=\"\">\n <pdfuaid:part>".concat(this.subset, "</pdfuaid:part>\n </rdf:Description>\n ");
6262
+ }
6263
+
6264
+ };
6265
+
6266
+ var SubsetMixin = {
6267
+ _importSubset(subset) {
6268
+ Object.assign(this, subset);
6269
+ },
6270
+
6271
+ initSubset(options) {
6272
+ switch (options.subset) {
6273
+ case 'PDF/A-1':
6274
+ case 'PDF/A-1a':
6275
+ case 'PDF/A-1b':
6276
+ case 'PDF/A-2':
6277
+ case 'PDF/A-2a':
6278
+ case 'PDF/A-2b':
6279
+ case 'PDF/A-3':
6280
+ case 'PDF/A-3a':
6281
+ case 'PDF/A-3b':
6282
+ this._importSubset(PDFA);
6283
+
6284
+ this.initPDFA(options.subset);
6285
+ break;
6286
+
6287
+ case 'PDF/UA':
6288
+ this._importSubset(PDFUA);
6289
+
6290
+ this.initPDFUA();
6291
+ break;
6292
+ }
6293
+ }
6294
+
6295
+ };
6296
+
6297
+ class PDFMetadata {
6298
+ constructor() {
6299
+ this._metadata = "\n <?xpacket begin=\"\uFEFF\" id=\"W5M0MpCehiHzreSzNTczkc9d\"?>\n <x:xmpmeta xmlns:x=\"adobe:ns:meta/\">\n <rdf:RDF xmlns:rdf=\"http://www.w3.org/1999/02/22-rdf-syntax-ns#\">\n ";
6300
+ }
6301
+
6302
+ _closeTags() {
6303
+ this._metadata = this._metadata.concat("\n </rdf:RDF>\n </x:xmpmeta>\n <?xpacket end=\"w\"?>\n ");
6304
+ }
6305
+
6306
+ append(xml) {
6307
+ var newline = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
6308
+ this._metadata = this._metadata.concat(xml);
6309
+ if (newline) this._metadata = this._metadata.concat('\n');
6310
+ }
6311
+
6312
+ getXML() {
6313
+ return this._metadata;
6314
+ }
6315
+
6316
+ getLength() {
6317
+ return this._metadata.length;
6318
+ }
6319
+
6320
+ end() {
6321
+ this._closeTags();
6322
+
6323
+ this._metadata = this._metadata.trim();
6324
+ }
6325
+
6326
+ }
6327
+
6328
+ var MetadataMixin = {
6329
+ initMetadata() {
6330
+ this.metadata = new PDFMetadata();
6331
+ },
6332
+
6333
+ appendXML(xml) {
6334
+ var newline = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
6335
+ this.metadata.append(xml, newline);
6336
+ },
6337
+
6338
+ _addInfo() {
6339
+ this.appendXML("\n <rdf:Description rdf:about=\"\" xmlns:xmp=\"http://ns.adobe.com/xap/1.0/\">\n <xmp:CreateDate>".concat(this.info.CreationDate.toISOString().split('.')[0] + "Z", "</xmp:CreateDate>\n <xmp:CreatorTool>").concat(this.info.Creator, "</xmp:CreatorTool>\n </rdf:Description>\n "));
6340
+
6341
+ if (this.info.Title || this.info.Author || this.info.Subject) {
6342
+ this.appendXML("\n <rdf:Description rdf:about=\"\" xmlns:dc=\"http://purl.org/dc/elements/1.1/\">\n ");
6343
+
6344
+ if (this.info.Title) {
6345
+ this.appendXML("\n <dc:title>\n <rdf:Alt>\n <rdf:li xml:lang=\"x-default\">".concat(this.info.Title, "</rdf:li>\n </rdf:Alt>\n </dc:title>\n "));
6346
+ }
6347
+
6348
+ if (this.info.Author) {
6349
+ this.appendXML("\n <dc:creator>\n <rdf:Seq>\n <rdf:li>".concat(this.info.Author, "</rdf:li>\n </rdf:Seq>\n </dc:creator>\n "));
6350
+ }
6351
+
6352
+ if (this.info.Subject) {
6353
+ this.appendXML("\n <dc:description>\n <rdf:Alt>\n <rdf:li xml:lang=\"x-default\">".concat(this.info.Subject, "</rdf:li>\n </rdf:Alt>\n </dc:description>\n "));
6354
+ }
6355
+
6356
+ this.appendXML("\n </rdf:Description>\n ");
6357
+ }
6358
+
6359
+ this.appendXML("\n <rdf:Description rdf:about=\"\" xmlns:pdf=\"http://ns.adobe.com/pdf/1.3/\">\n <pdf:Producer>".concat(this.info.Creator, "</pdf:Producer>"), false);
6360
+
6361
+ if (this.info.Keywords) {
6362
+ this.appendXML("\n <pdf:Keywords>".concat(this.info.Keywords, "</pdf:Keywords>"), false);
6363
+ }
6364
+
6365
+ this.appendXML("\n </rdf:Description>\n ");
6366
+ },
6367
+
6368
+ endMetadata() {
6369
+ this._addInfo();
6370
+
6371
+ this.metadata.end();
6372
+ /*
6373
+ Metadata was introduced in PDF 1.4, so adding it to 1.3
6374
+ will likely only take up more space.
6375
+ */
6376
+
6377
+ if (this.version != 1.3) {
6378
+ this.metadataRef = this.ref({
6379
+ length: this.metadata.getLength(),
6380
+ Type: 'Metadata',
6381
+ Subtype: 'XML'
6382
+ });
6383
+ this.metadataRef.compress = false;
6384
+ this.metadataRef.write(Buffer.from(this.metadata.getXML(), 'utf-8'));
6385
+ this.metadataRef.end();
6386
+ this._root.data.Metadata = this.metadataRef;
6387
+ }
6388
+ }
6389
+
6390
+ };
6391
+
6047
6392
  /*
6048
6393
  PDFDocument - represents an entire PDF document
6049
6394
  By Devon Govett
@@ -6108,13 +6453,15 @@ class PDFDocument extends stream.Readable {
6108
6453
 
6109
6454
  this.page = null; // Initialize mixins
6110
6455
 
6456
+ this.initMetadata();
6111
6457
  this.initColor();
6112
6458
  this.initVector();
6113
6459
  this.initFonts(options.font);
6114
6460
  this.initText();
6115
6461
  this.initImages();
6116
6462
  this.initOutline();
6117
- this.initMarkings(options); // Initialize the metadata
6463
+ this.initMarkings(options);
6464
+ this.initSubset(options); // Initialize the metadata
6118
6465
 
6119
6466
  this.info = {
6120
6467
  Producer: 'PDFKit',
@@ -6336,6 +6683,12 @@ class PDFDocument extends stream.Readable {
6336
6683
  this.endOutline();
6337
6684
  this.endMarkings();
6338
6685
 
6686
+ if (this.subset) {
6687
+ this.endSubset();
6688
+ }
6689
+
6690
+ this.endMetadata();
6691
+
6339
6692
  this._root.end();
6340
6693
 
6341
6694
  this._root.data.Pages.end();
@@ -6411,6 +6764,7 @@ var mixin = methods => {
6411
6764
  Object.assign(PDFDocument.prototype, methods);
6412
6765
  };
6413
6766
 
6767
+ mixin(MetadataMixin);
6414
6768
  mixin(ColorMixin);
6415
6769
  mixin(VectorMixin);
6416
6770
  mixin(FontsMixin);
@@ -6421,6 +6775,7 @@ mixin(OutlineMixin);
6421
6775
  mixin(MarkingsMixin);
6422
6776
  mixin(AcroFormMixin);
6423
6777
  mixin(AttachmentsMixin);
6778
+ mixin(SubsetMixin);
6424
6779
  PDFDocument.LineWrapper = LineWrapper;
6425
6780
 
6426
6781
  export default PDFDocument;