pdfkit 0.12.3 → 0.14.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 CHANGED
@@ -1,6 +1,17 @@
1
1
  ## pdfkit changelog
2
2
 
3
- ### Unreleased
3
+ ### [v0.14.0] - 2023-11-09
4
+
5
+ - Add support for PDF/A-1b, PDF/A-1a, PDF/A-2b, PDF/A-2a, PDF/A-3b, PDF/A-3a
6
+ - Update crypto-js to v4.2.0 (properly fix security issue)
7
+
8
+ ### [v0.13.0] - 2021-10-24
9
+
10
+ - Add tiling pattern support
11
+
12
+ ### [v0.12.3] - 2021-08-01
13
+
14
+ - Remove examples from published package
4
15
 
5
16
  ### [v0.12.2] - 2021-08-01
6
17
 
package/README.md CHANGED
@@ -154,7 +154,7 @@ const stream = doc.pipe(blobStream());
154
154
 
155
155
  // add your content to the document here, as usual
156
156
 
157
- // get a blob when you're done
157
+ // get a blob when you are done
158
158
  doc.end();
159
159
  stream.on('finish', function() {
160
160
  // get a blob you can do whatever you like with
Binary file
package/js/pdfkit.es5.js CHANGED
@@ -762,6 +762,12 @@ var PDFPage = /*#__PURE__*/function () {
762
762
  var data = this.resources.data;
763
763
  return data.Pattern != null ? data.Pattern : data.Pattern = {};
764
764
  }
765
+ }, {
766
+ key: "colorSpaces",
767
+ get: function get() {
768
+ var data = this.resources.data;
769
+ return data.ColorSpace || (data.ColorSpace = {});
770
+ }
765
771
  }, {
766
772
  key: "annotations",
767
773
  get: function get() {
@@ -1891,7 +1897,7 @@ var PDFGradient = /*#__PURE__*/function () {
1891
1897
  }
1892
1898
  }, {
1893
1899
  key: "apply",
1894
- value: function apply(op) {
1900
+ value: function apply(stroke) {
1895
1901
  // apply gradient transform to existing document ctm
1896
1902
  var _this$doc$_ctm = _slicedToArray(this.doc._ctm, 6),
1897
1903
  m0 = _this$doc$_ctm[0],
@@ -1915,6 +1921,9 @@ var PDFGradient = /*#__PURE__*/function () {
1915
1921
  this.embed(m);
1916
1922
  }
1917
1923
 
1924
+ this.doc._setColorSpace('Pattern', stroke);
1925
+
1926
+ var op = stroke ? 'SCN' : 'scn';
1918
1927
  return this.doc.addContent("/".concat(this.id, " ").concat(op));
1919
1928
  }
1920
1929
  }]);
@@ -2009,21 +2018,143 @@ var Gradient = {
2009
2018
  PDFRadialGradient: PDFRadialGradient
2010
2019
  };
2011
2020
 
2021
+ /*
2022
+ PDF tiling pattern support. Uncolored only.
2023
+ */
2024
+ var underlyingColorSpaces = ['DeviceCMYK', 'DeviceRGB'];
2025
+
2026
+ var PDFTilingPattern = /*#__PURE__*/function () {
2027
+ function PDFTilingPattern(doc, bBox, xStep, yStep, stream) {
2028
+ _classCallCheck(this, PDFTilingPattern);
2029
+
2030
+ this.doc = doc;
2031
+ this.bBox = bBox;
2032
+ this.xStep = xStep;
2033
+ this.yStep = yStep;
2034
+ this.stream = stream;
2035
+ }
2036
+
2037
+ _createClass(PDFTilingPattern, [{
2038
+ key: "createPattern",
2039
+ value: function createPattern() {
2040
+ // no resources needed for our current usage
2041
+ // required entry
2042
+ var resources = this.doc.ref();
2043
+ resources.end(); // apply default transform matrix (flipped in the default doc._ctm)
2044
+ // see document.js & gradient.js
2045
+
2046
+ var _this$doc$_ctm = _slicedToArray(this.doc._ctm, 6),
2047
+ m0 = _this$doc$_ctm[0],
2048
+ m1 = _this$doc$_ctm[1],
2049
+ m2 = _this$doc$_ctm[2],
2050
+ m3 = _this$doc$_ctm[3],
2051
+ m4 = _this$doc$_ctm[4],
2052
+ m5 = _this$doc$_ctm[5];
2053
+
2054
+ var m11 = 1,
2055
+ m12 = 0,
2056
+ m21 = 0,
2057
+ m22 = 1,
2058
+ dx = 0,
2059
+ dy = 0;
2060
+ var m = [m0 * m11 + m2 * m12, m1 * m11 + m3 * m12, m0 * m21 + m2 * m22, m1 * m21 + m3 * m22, m0 * dx + m2 * dy + m4, m1 * dx + m3 * dy + m5];
2061
+ var pattern = this.doc.ref({
2062
+ Type: 'Pattern',
2063
+ PatternType: 1,
2064
+ // tiling
2065
+ PaintType: 2,
2066
+ // 1-colored, 2-uncolored
2067
+ TilingType: 2,
2068
+ // 2-no distortion
2069
+ BBox: this.bBox,
2070
+ XStep: this.xStep,
2071
+ YStep: this.yStep,
2072
+ Matrix: m.map(function (v) {
2073
+ return +v.toFixed(5);
2074
+ }),
2075
+ Resources: resources
2076
+ });
2077
+ pattern.end(this.stream);
2078
+ return pattern;
2079
+ }
2080
+ }, {
2081
+ key: "embedPatternColorSpaces",
2082
+ value: function embedPatternColorSpaces() {
2083
+ var _this = this;
2084
+
2085
+ // map each pattern to an underlying color space
2086
+ // and embed on each page
2087
+ underlyingColorSpaces.forEach(function (csName) {
2088
+ var csId = _this.getPatternColorSpaceId(csName);
2089
+
2090
+ if (_this.doc.page.colorSpaces[csId]) return;
2091
+
2092
+ var cs = _this.doc.ref(['Pattern', csName]);
2093
+
2094
+ cs.end();
2095
+ _this.doc.page.colorSpaces[csId] = cs;
2096
+ });
2097
+ }
2098
+ }, {
2099
+ key: "getPatternColorSpaceId",
2100
+ value: function getPatternColorSpaceId(underlyingColorspace) {
2101
+ return "CsP".concat(underlyingColorspace);
2102
+ }
2103
+ }, {
2104
+ key: "embed",
2105
+ value: function embed() {
2106
+ if (!this.id) {
2107
+ this.doc._patternCount = this.doc._patternCount + 1;
2108
+ this.id = 'P' + this.doc._patternCount;
2109
+ this.pattern = this.createPattern();
2110
+ } // patterns are embedded in each page
2111
+
2112
+
2113
+ if (!this.doc.page.patterns[this.id]) {
2114
+ this.doc.page.patterns[this.id] = this.pattern;
2115
+ }
2116
+ }
2117
+ }, {
2118
+ key: "apply",
2119
+ value: function apply(stroke, patternColor) {
2120
+ // do any embedding/creating that might be needed
2121
+ this.embedPatternColorSpaces();
2122
+ this.embed();
2123
+
2124
+ var normalizedColor = this.doc._normalizeColor(patternColor);
2125
+
2126
+ if (!normalizedColor) throw Error("invalid pattern color. (value: ".concat(patternColor, ")")); // select one of the pattern color spaces
2127
+
2128
+ var csId = this.getPatternColorSpaceId(this.doc._getColorSpace(normalizedColor));
2129
+
2130
+ this.doc._setColorSpace(csId, stroke); // stroke/fill using the pattern and color (in the above underlying color space)
2131
+
2132
+
2133
+ var op = stroke ? 'SCN' : 'scn';
2134
+ return this.doc.addContent("".concat(normalizedColor.join(' '), " /").concat(this.id, " ").concat(op));
2135
+ }
2136
+ }]);
2137
+
2138
+ return PDFTilingPattern;
2139
+ }();
2140
+
2141
+ var pattern = {
2142
+ PDFTilingPattern: PDFTilingPattern
2143
+ };
2144
+
2012
2145
  var PDFGradient$1 = Gradient.PDFGradient,
2013
2146
  PDFLinearGradient$1 = Gradient.PDFLinearGradient,
2014
2147
  PDFRadialGradient$1 = Gradient.PDFRadialGradient;
2148
+ var PDFTilingPattern$1 = pattern.PDFTilingPattern;
2015
2149
  var ColorMixin = {
2016
2150
  initColor: function initColor() {
2017
2151
  // The opacity dictionaries
2018
2152
  this._opacityRegistry = {};
2019
2153
  this._opacityCount = 0;
2154
+ this._patternCount = 0;
2020
2155
  return this._gradCount = 0;
2021
2156
  },
2022
2157
  _normalizeColor: function _normalizeColor(color) {
2023
- if (color instanceof PDFGradient$1) {
2024
- return color;
2025
- }
2026
-
2027
2158
  if (typeof color === 'string') {
2028
2159
  if (color.charAt(0) === '#') {
2029
2160
  if (color.length === 4) {
@@ -2055,6 +2186,18 @@ var ColorMixin = {
2055
2186
  return null;
2056
2187
  },
2057
2188
  _setColor: function _setColor(color, stroke) {
2189
+ if (color instanceof PDFGradient$1) {
2190
+ color.apply(stroke);
2191
+ return true; // see if tiling pattern, decode & apply it it
2192
+ } else if (Array.isArray(color) && color[0] instanceof PDFTilingPattern$1) {
2193
+ color[0].apply(stroke, color[1]);
2194
+ return true;
2195
+ } // any other case should be a normal color and not a pattern
2196
+
2197
+
2198
+ return this._setColorCore(color, stroke);
2199
+ },
2200
+ _setColorCore: function _setColorCore(color, stroke) {
2058
2201
  color = this._normalizeColor(color);
2059
2202
 
2060
2203
  if (!color) {
@@ -2063,25 +2206,21 @@ var ColorMixin = {
2063
2206
 
2064
2207
  var op = stroke ? 'SCN' : 'scn';
2065
2208
 
2066
- if (color instanceof PDFGradient$1) {
2067
- this._setColorSpace('Pattern', stroke);
2068
-
2069
- color.apply(op);
2070
- } else {
2071
- var space = color.length === 4 ? 'DeviceCMYK' : 'DeviceRGB';
2072
-
2073
- this._setColorSpace(space, stroke);
2209
+ var space = this._getColorSpace(color);
2074
2210
 
2075
- color = color.join(' ');
2076
- this.addContent("".concat(color, " ").concat(op));
2077
- }
2211
+ this._setColorSpace(space, stroke);
2078
2212
 
2213
+ color = color.join(' ');
2214
+ this.addContent("".concat(color, " ").concat(op));
2079
2215
  return true;
2080
2216
  },
2081
2217
  _setColorSpace: function _setColorSpace(space, stroke) {
2082
2218
  var op = stroke ? 'CS' : 'cs';
2083
2219
  return this.addContent("/".concat(space, " ").concat(op));
2084
2220
  },
2221
+ _getColorSpace: function _getColorSpace(color) {
2222
+ return color.length === 4 ? 'DeviceCMYK' : 'DeviceRGB';
2223
+ },
2085
2224
  fillColor: function fillColor(color, opacity) {
2086
2225
  var set = this._setColor(color, false);
2087
2226
 
@@ -2168,6 +2307,9 @@ var ColorMixin = {
2168
2307
  },
2169
2308
  radialGradient: function radialGradient(x1, y1, r1, x2, y2, r2) {
2170
2309
  return new PDFRadialGradient$1(this, x1, y1, r1, x2, y2, r2);
2310
+ },
2311
+ pattern: function pattern(bbox, xStep, yStep, stream) {
2312
+ return new PDFTilingPattern$1(this, bbox, xStep, yStep, stream);
2171
2313
  }
2172
2314
  };
2173
2315
  var namedColors = {
@@ -3649,6 +3791,14 @@ var EmbeddedFont = /*#__PURE__*/function (_PDFFont) {
3649
3791
  descriptor.data.FontFile2 = fontFile;
3650
3792
  }
3651
3793
 
3794
+ if (this.document.subset) {
3795
+ var CIDSet = Buffer.from('FFFFFFFFC0', 'hex');
3796
+ var CIDSetRef = this.document.ref();
3797
+ CIDSetRef.write(CIDSet);
3798
+ CIDSetRef.end();
3799
+ descriptor.data.CIDSet = CIDSetRef;
3800
+ }
3801
+
3652
3802
  descriptor.end();
3653
3803
  var descendantFontData = {
3654
3804
  Type: 'Font',
@@ -6552,6 +6702,175 @@ function isEqual(a, b) {
6552
6702
  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;
6553
6703
  }
6554
6704
 
6705
+ var PDFA = {
6706
+ initPDFA: function initPDFA(pSubset) {
6707
+ if (pSubset.charAt(pSubset.length - 3) === '-') {
6708
+ this.subset_conformance = pSubset.charAt(pSubset.length - 1).toUpperCase();
6709
+ this.subset = parseInt(pSubset.charAt(pSubset.length - 2));
6710
+ } else {
6711
+ // Default to Basic conformance when user doesn't specify
6712
+ this.subset_conformance = 'B';
6713
+ this.subset = parseInt(pSubset.charAt(pSubset.length - 1));
6714
+ }
6715
+ },
6716
+ endSubset: function endSubset() {
6717
+ this._addPdfaMetadata();
6718
+
6719
+ var jsPath = "".concat(__dirname, "/data/sRGB_IEC61966_2_1.icc");
6720
+ var jestPath = "".concat(__dirname, "/../color_profiles/sRGB_IEC61966_2_1.icc");
6721
+
6722
+ this._addColorOutputIntent(fs.existsSync(jsPath) ? jsPath : jestPath);
6723
+ },
6724
+ _addColorOutputIntent: function _addColorOutputIntent(pICCPath) {
6725
+ var iccProfile = fs.readFileSync(pICCPath);
6726
+ var colorProfileRef = this.ref({
6727
+ Length: iccProfile.length,
6728
+ N: 3
6729
+ });
6730
+ colorProfileRef.write(iccProfile);
6731
+ colorProfileRef.end();
6732
+ var intentRef = this.ref({
6733
+ Type: 'OutputIntent',
6734
+ S: 'GTS_PDFA1',
6735
+ Info: new String('sRGB IEC61966-2.1'),
6736
+ OutputConditionIdentifier: new String('sRGB IEC61966-2.1'),
6737
+ DestOutputProfile: colorProfileRef
6738
+ });
6739
+ intentRef.end();
6740
+ this._root.data.OutputIntents = [intentRef];
6741
+ },
6742
+ _getPdfaid: function _getPdfaid() {
6743
+ 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 ");
6744
+ },
6745
+ _addPdfaMetadata: function _addPdfaMetadata() {
6746
+ this.appendXML(this._getPdfaid());
6747
+ }
6748
+ };
6749
+
6750
+ var SubsetMixin = {
6751
+ _importSubset: function _importSubset(subset) {
6752
+ Object.assign(this, subset);
6753
+ },
6754
+ initSubset: function initSubset(options) {
6755
+ switch (options.subset) {
6756
+ case 'PDF/A-1':
6757
+ case 'PDF/A-1a':
6758
+ case 'PDF/A-1b':
6759
+ case 'PDF/A-2':
6760
+ case 'PDF/A-2a':
6761
+ case 'PDF/A-2b':
6762
+ case 'PDF/A-3':
6763
+ case 'PDF/A-3a':
6764
+ case 'PDF/A-3b':
6765
+ this._importSubset(PDFA);
6766
+
6767
+ this.initPDFA(options.subset);
6768
+ break;
6769
+ }
6770
+ }
6771
+ };
6772
+
6773
+ var PDFMetadata = /*#__PURE__*/function () {
6774
+ function PDFMetadata() {
6775
+ _classCallCheck(this, PDFMetadata);
6776
+
6777
+ 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 ";
6778
+ }
6779
+
6780
+ _createClass(PDFMetadata, [{
6781
+ key: "_closeTags",
6782
+ value: function _closeTags() {
6783
+ this._metadata = this._metadata.concat("\n </rdf:RDF>\n </x:xmpmeta>\n <?xpacket end=\"w\"?>\n ");
6784
+ }
6785
+ }, {
6786
+ key: "append",
6787
+ value: function append(xml) {
6788
+ var newline = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
6789
+ this._metadata = this._metadata.concat(xml);
6790
+ if (newline) this._metadata = this._metadata.concat('\n');
6791
+ }
6792
+ }, {
6793
+ key: "getXML",
6794
+ value: function getXML() {
6795
+ return this._metadata;
6796
+ }
6797
+ }, {
6798
+ key: "getLength",
6799
+ value: function getLength() {
6800
+ return this._metadata.length;
6801
+ }
6802
+ }, {
6803
+ key: "end",
6804
+ value: function end() {
6805
+ this._closeTags();
6806
+
6807
+ this._metadata = this._metadata.trim();
6808
+ }
6809
+ }]);
6810
+
6811
+ return PDFMetadata;
6812
+ }();
6813
+
6814
+ var MetadataMixin = {
6815
+ initMetadata: function initMetadata() {
6816
+ this.metadata = new PDFMetadata();
6817
+ },
6818
+ appendXML: function appendXML(xml) {
6819
+ var newline = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
6820
+ this.metadata.append(xml, newline);
6821
+ },
6822
+ _addInfo: function _addInfo() {
6823
+ 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 "));
6824
+
6825
+ if (this.info.Title || this.info.Author || this.info.Subject) {
6826
+ this.appendXML("\n <rdf:Description rdf:about=\"\" xmlns:dc=\"http://purl.org/dc/elements/1.1/\">\n ");
6827
+
6828
+ if (this.info.Title) {
6829
+ 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 "));
6830
+ }
6831
+
6832
+ if (this.info.Author) {
6833
+ this.appendXML("\n <dc:creator>\n <rdf:Seq>\n <rdf:li>".concat(this.info.Author, "</rdf:li>\n </rdf:Seq>\n </dc:creator>\n "));
6834
+ }
6835
+
6836
+ if (this.info.Subject) {
6837
+ 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 "));
6838
+ }
6839
+
6840
+ this.appendXML("\n </rdf:Description>\n ");
6841
+ }
6842
+
6843
+ 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);
6844
+
6845
+ if (this.info.Keywords) {
6846
+ this.appendXML("\n <pdf:Keywords>".concat(this.info.Keywords, "</pdf:Keywords>"), false);
6847
+ }
6848
+
6849
+ this.appendXML("\n </rdf:Description>\n ");
6850
+ },
6851
+ endMetadata: function endMetadata() {
6852
+ this._addInfo();
6853
+
6854
+ this.metadata.end();
6855
+ /*
6856
+ Metadata was introduced in PDF 1.4, so adding it to 1.3
6857
+ will likely only take up more space.
6858
+ */
6859
+
6860
+ if (this.version != 1.3) {
6861
+ this.metadataRef = this.ref({
6862
+ length: this.metadata.getLength(),
6863
+ Type: 'Metadata',
6864
+ Subtype: 'XML'
6865
+ });
6866
+ this.metadataRef.compress = false;
6867
+ this.metadataRef.write(Buffer.from(this.metadata.getXML(), 'utf-8'));
6868
+ this.metadataRef.end();
6869
+ this._root.data.Metadata = this.metadataRef;
6870
+ }
6871
+ }
6872
+ };
6873
+
6555
6874
  var PDFDocument = /*#__PURE__*/function (_stream$Readable) {
6556
6875
  _inherits(PDFDocument, _stream$Readable);
6557
6876
 
@@ -6623,6 +6942,8 @@ var PDFDocument = /*#__PURE__*/function (_stream$Readable) {
6623
6942
 
6624
6943
  _this.page = null; // Initialize mixins
6625
6944
 
6945
+ _this.initMetadata();
6946
+
6626
6947
  _this.initColor();
6627
6948
 
6628
6949
  _this.initVector();
@@ -6635,7 +6956,9 @@ var PDFDocument = /*#__PURE__*/function (_stream$Readable) {
6635
6956
 
6636
6957
  _this.initOutline();
6637
6958
 
6638
- _this.initMarkings(options); // Initialize the metadata
6959
+ _this.initMarkings(options);
6960
+
6961
+ _this.initSubset(options); // Initialize the metadata
6639
6962
 
6640
6963
 
6641
6964
  _this.info = {
@@ -6884,6 +7207,12 @@ var PDFDocument = /*#__PURE__*/function (_stream$Readable) {
6884
7207
  this.endOutline();
6885
7208
  this.endMarkings();
6886
7209
 
7210
+ if (this.subset) {
7211
+ this.endSubset();
7212
+ }
7213
+
7214
+ this.endMetadata();
7215
+
6887
7216
  this._root.end();
6888
7217
 
6889
7218
  this._root.data.Pages.end();
@@ -6973,6 +7302,7 @@ var mixin = function mixin(methods) {
6973
7302
  Object.assign(PDFDocument.prototype, methods);
6974
7303
  };
6975
7304
 
7305
+ mixin(MetadataMixin);
6976
7306
  mixin(ColorMixin);
6977
7307
  mixin(VectorMixin);
6978
7308
  mixin(FontsMixin);
@@ -6983,6 +7313,7 @@ mixin(OutlineMixin);
6983
7313
  mixin(MarkingsMixin);
6984
7314
  mixin(AcroFormMixin);
6985
7315
  mixin(AttachmentsMixin);
7316
+ mixin(SubsetMixin);
6986
7317
  PDFDocument.LineWrapper = LineWrapper;
6987
7318
 
6988
7319
  export default PDFDocument;