@kittl/pdfkit 0.17.4 → 0.17.51

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.
Binary file
package/js/pdfkit.es.js CHANGED
@@ -954,14 +954,18 @@ class PDFGradient$1 {
954
954
  }
955
955
  color = this.doc._normalizeColor(color);
956
956
  if (this.stops.length === 0) {
957
- if (color.length === 3) {
958
- this._colorSpace = 'DeviceRGB';
959
- } else if (color.length === 4) {
960
- this._colorSpace = 'DeviceCMYK';
961
- } else if (color.length === 1) {
962
- this._colorSpace = 'DeviceGray';
957
+ if (this._activeColorProfile) {
958
+ this._colorSpace = this._activeColorProfile.ref;
963
959
  } else {
964
- throw new Error('Unknown color space');
960
+ if (color.length === 3) {
961
+ this._colorSpace = 'DeviceRGB';
962
+ } else if (color.length === 4) {
963
+ this._colorSpace = 'DeviceCMYK';
964
+ } else if (color.length === 1) {
965
+ this._colorSpace = 'DeviceGray';
966
+ } else {
967
+ throw new Error('Unknown color space');
968
+ }
965
969
  }
966
970
  } else if (this._colorSpace === 'DeviceRGB' && color.length !== 3 || this._colorSpace === 'DeviceCMYK' && color.length !== 4 || this._colorSpace === 'DeviceGray' && color.length !== 1) {
967
971
  throw new Error('All gradient stops must use the same color space');
@@ -1252,7 +1256,7 @@ var ColorMixin = {
1252
1256
  if (color.length === 3) {
1253
1257
  color = color.map(part => part / 255);
1254
1258
  } else if (color.length === 4) {
1255
- color = color.map(part => part / 255);
1259
+ color = color.map(part => part / 100);
1256
1260
  }
1257
1261
  return color;
1258
1262
  }
@@ -1328,7 +1332,7 @@ var ColorMixin = {
1328
1332
  this._doOpacity(null, opacity);
1329
1333
  return this;
1330
1334
  },
1331
- beingColorProfile(label) {
1335
+ beginColorSpace(label) {
1332
1336
  const profile = this._colorProfiles[label];
1333
1337
  if (!profile) {
1334
1338
  throw Error('Invalid color space label, the profile should be set first');
@@ -1336,7 +1340,7 @@ var ColorMixin = {
1336
1340
  this._activeColorProfile = profile;
1337
1341
  return this;
1338
1342
  },
1339
- endColorProfile() {
1343
+ endColorSpace() {
1340
1344
  this._activeColorProfile = null;
1341
1345
  return this;
1342
1346
  },
@@ -3979,10 +3983,102 @@ class PNGImage {
3979
3983
  }
3980
3984
  }
3981
3985
 
3986
+ class BitmapImage {
3987
+ constructor(data, label, properties) {
3988
+ this.label = label;
3989
+ this.data = data;
3990
+ this.width = properties.width;
3991
+ this.height = properties.height;
3992
+ this.channels = properties.channels;
3993
+ this.colorSpace = properties.colorSpace;
3994
+ this.hasAlphaChannel = properties.hasAlphaChannel;
3995
+ this.obj = null;
3996
+ }
3997
+ embed(document) {
3998
+ if (this.obj) {
3999
+ return;
4000
+ }
4001
+ this.document = document;
4002
+ if (!(this.data instanceof Uint8Array && this.data.length === this.channels * this.width * this.height)) {
4003
+ throw Error("Invalid bitmap, data doesn't match the given properties.");
4004
+ }
4005
+ if (this.colorSpace) {
4006
+ const profile = this.document._colorProfiles[this.colorSpace];
4007
+ if (!profile) {
4008
+ throw Error("PDFDocument doesn't support bitmap color space.");
4009
+ }
4010
+ const channels = this.hasAlphaChannel ? this.channels - 1 : this.channels;
4011
+ if (profile.channels !== channels) {
4012
+ throw Error("Color profile doesn't support image channels");
4013
+ }
4014
+ this.colorSpace = profile.ref;
4015
+ } else {
4016
+ if (!this.hasAlphaChannel) {
4017
+ this.colorSpace = this.channels === 4 ? 'DeviceCMYK' : 'DeviceRGB';
4018
+ } else {
4019
+ this.colorSpace = this.channels === 5 ? 'DeviceCMYK' : 'DeviceRGB';
4020
+ }
4021
+ }
4022
+ let pixelData = this.data;
4023
+ let alphaData = undefined;
4024
+ if (this.hasAlphaChannel) {
4025
+ const pixelChannels = this.channels - 1;
4026
+ pixelData = new Uint8Array(pixelChannels * this.width * this.height);
4027
+ alphaData = new Uint8Array(this.width * this.height);
4028
+ if (this.channels === 4) {
4029
+ for (let src = 0, dst = 0, a = 0; a < this.data.length; src += 4, dst += 3, a++) {
4030
+ pixelData[dst] = this.data[src];
4031
+ pixelData[dst + 1] = this.data[src + 1];
4032
+ pixelData[dst + 2] = this.data[src + 2];
4033
+ alphaData[a] = this.data[src + 3];
4034
+ }
4035
+ } else if (this.channels === 5) {
4036
+ for (let src = 0, dst = 0, a = 0; a < this.data.length; src += 5, dst += 4, a++) {
4037
+ pixelData[dst] = this.data[src];
4038
+ pixelData[dst + 1] = this.data[src + 1];
4039
+ pixelData[dst + 2] = this.data[src + 2];
4040
+ pixelData[dst + 3] = this.data[src + 3];
4041
+ alphaData[a] = this.data[src + 4];
4042
+ }
4043
+ } else {
4044
+ for (let src = 0, dst = 0, a = 0; a < this.data.length; src += this.channels, dst += pixelChannels, a++) {
4045
+ for (let j = 0; j < pixelChannels; j++) {
4046
+ pixelData[dst + j] = this.data[src + j];
4047
+ }
4048
+ alphaData[a] = this.data[src + pixelChannels];
4049
+ }
4050
+ }
4051
+ }
4052
+ this.obj = this.document.ref({
4053
+ Type: 'XObject',
4054
+ Subtype: 'Image',
4055
+ BitsPerComponent: 8,
4056
+ Width: this.width,
4057
+ Height: this.height,
4058
+ ColorSpace: this.colorSpace
4059
+ });
4060
+ if (alphaData) {
4061
+ const sMask = this.document.ref({
4062
+ Type: 'XObject',
4063
+ Subtype: 'Image',
4064
+ Height: this.height,
4065
+ Width: this.width,
4066
+ BitsPerComponent: 8,
4067
+ ColorSpace: 'DeviceGray',
4068
+ Decode: [0, 1]
4069
+ });
4070
+ sMask.end(alphaData);
4071
+ this.obj.data['SMask'] = sMask;
4072
+ }
4073
+ this.obj.end(pixelData);
4074
+ this.data = null;
4075
+ }
4076
+ }
4077
+
3982
4078
  class PDFImage {
3983
- static open(src, label) {
4079
+ static open(src, label, properties) {
3984
4080
  let data;
3985
- if (Buffer.isBuffer(src)) {
4081
+ if (src instanceof Uint8Array || Buffer.isBuffer(src)) {
3986
4082
  data = src;
3987
4083
  } else if (src instanceof ArrayBuffer) {
3988
4084
  data = Buffer.from(new Uint8Array(src));
@@ -4000,6 +4096,9 @@ class PDFImage {
4000
4096
  }
4001
4097
  }
4002
4098
  }
4099
+ if (properties?.isBitmap) {
4100
+ return new BitmapImage(data, label, properties);
4101
+ }
4003
4102
  if (data[0] === 0xff && data[1] === 0xd8) {
4004
4103
  return new JPEG(data, label);
4005
4104
  } else if (data[0] === 0x89 && data.toString('ascii', 1, 4) === 'PNG') {
@@ -4184,13 +4283,13 @@ var ImagesMixin = {
4184
4283
  this.restore();
4185
4284
  return this;
4186
4285
  },
4187
- openImage(src) {
4286
+ openImage(src, properties) {
4188
4287
  let image;
4189
4288
  if (typeof src === 'string') {
4190
4289
  image = this._imageRegistry[src];
4191
4290
  }
4192
4291
  if (!image) {
4193
- image = PDFImage.open(src, `I${++this._imageCount}`);
4292
+ image = PDFImage.open(src, `I${++this._imageCount}`, properties);
4194
4293
  if (typeof src === 'string') {
4195
4294
  this._imageRegistry[src] = image;
4196
4295
  }
@@ -6114,8 +6213,7 @@ class ICCProfile {
6114
6213
  N: this.channels,
6115
6214
  Length: this.data.length
6116
6215
  });
6117
- this.streamRef.write(this.data);
6118
- this.streamRef.end();
6216
+ this.streamRef.end(this.data);
6119
6217
  this.ref = this.document.ref([`ICCBased ${this.streamRef}`]);
6120
6218
  this.ref.end();
6121
6219
  this.data = null;