pdfkit 0.17.0 → 0.17.2

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.js CHANGED
@@ -221,8 +221,18 @@ class PDFReference extends PDFAbstractReference {
221
221
  }
222
222
  }
223
223
 
224
+ const fArray = new Float32Array(1);
225
+ const uArray = new Uint32Array(fArray.buffer);
224
226
  function PDFNumber(n) {
225
- return Math.fround(n);
227
+ const rounded = Math.fround(n);
228
+ if (rounded <= n) return rounded;
229
+ fArray[0] = n;
230
+ if (n <= 0) {
231
+ uArray[0] += 1;
232
+ } else {
233
+ uArray[0] -= 1;
234
+ }
235
+ return fArray[0];
226
236
  }
227
237
  function normalizeSides(sides, defaultDefinition = undefined, transformer = v => v) {
228
238
  if (sides == null || typeof sides === 'object' && Object.keys(sides).length === 0) {
@@ -2137,20 +2147,12 @@ oslash ugrave uacute ucircumflex
2137
2147
  udieresis yacute thorn ydieresis\
2138
2148
  `.split(/\s+/);
2139
2149
  class AFMFont {
2140
- static open(filename) {
2141
- return new AFMFont(fs.readFileSync(filename, 'utf8'));
2142
- }
2143
2150
  constructor(contents) {
2144
- this.contents = contents;
2145
2151
  this.attributes = {};
2146
2152
  this.glyphWidths = {};
2147
2153
  this.boundingBoxes = {};
2148
2154
  this.kernPairs = {};
2149
- this.parse();
2150
- this.charWidths = new Array(256);
2151
- for (let char = 0; char <= 255; char++) {
2152
- this.charWidths[char] = this.glyphWidths[characters[char]];
2153
- }
2155
+ this.parse(contents);
2154
2156
  this.bbox = this.attributes['FontBBox'].split(/\s+/).map(e => +e);
2155
2157
  this.ascender = +(this.attributes['Ascender'] || 0);
2156
2158
  this.descender = +(this.attributes['Descender'] || 0);
@@ -2158,9 +2160,9 @@ class AFMFont {
2158
2160
  this.capHeight = +(this.attributes['CapHeight'] || 0);
2159
2161
  this.lineGap = this.bbox[3] - this.bbox[1] - (this.ascender - this.descender);
2160
2162
  }
2161
- parse() {
2163
+ parse(contents) {
2162
2164
  let section = '';
2163
- for (let line of this.contents.split('\n')) {
2165
+ for (let line of contents.split('\n')) {
2164
2166
  var match;
2165
2167
  var a;
2166
2168
  if (match = line.match(/^Start(\w+)/)) {
@@ -2813,7 +2815,7 @@ class LineWrapper extends events.EventEmitter {
2813
2815
  });
2814
2816
  }
2815
2817
  wordWidth(word) {
2816
- return this.document.widthOfString(word, this) + this.characterSpacing + this.wordSpacing;
2818
+ return PDFNumber(this.document.widthOfString(word, this) + this.characterSpacing + this.wordSpacing);
2817
2819
  }
2818
2820
  canFit(word, w) {
2819
2821
  if (word[word.length - 1] != SOFT_HYPHEN) {
@@ -2954,12 +2956,14 @@ class LineWrapper extends events.EventEmitter {
2954
2956
  }
2955
2957
  emitLine();
2956
2958
  if (PDFNumber(this.document.y + lh) > this.maxY) {
2959
+ this.emit('sectionEnd', options, this);
2957
2960
  const shouldContinue = this.nextSection();
2958
2961
  if (!shouldContinue) {
2959
2962
  wc = 0;
2960
2963
  buffer = '';
2961
2964
  return false;
2962
2965
  }
2966
+ this.emit('sectionStart', options, this);
2963
2967
  }
2964
2968
  if (bk.required) {
2965
2969
  this.spaceLeft = this.lineWidth;
@@ -2992,7 +2996,6 @@ class LineWrapper extends events.EventEmitter {
2992
2996
  }
2993
2997
  }
2994
2998
  nextSection(options) {
2995
- this.emit('sectionEnd', options, this);
2996
2999
  if (++this.column > this.columns) {
2997
3000
  if (this.height != null) {
2998
3001
  return false;
@@ -3011,7 +3014,6 @@ class LineWrapper extends events.EventEmitter {
3011
3014
  this.document.y = this.startY;
3012
3015
  this.emit('columnBreak', options, this);
3013
3016
  }
3014
- this.emit('sectionStart', options, this);
3015
3017
  return true;
3016
3018
  }
3017
3019
  }
@@ -3019,6 +3021,15 @@ class LineWrapper extends events.EventEmitter {
3019
3021
  const {
3020
3022
  number
3021
3023
  } = PDFObject;
3024
+ function formatListLabel(n, listType) {
3025
+ if (listType === 'numbered') {
3026
+ return `${n}.`;
3027
+ }
3028
+ var letter = String.fromCharCode((n - 1) % 26 + 65);
3029
+ var times = Math.floor((n - 1) / 26 + 1);
3030
+ var text = Array(times + 1).join(letter);
3031
+ return `${text}.`;
3032
+ }
3022
3033
  var TextMixin = {
3023
3034
  initText() {
3024
3035
  this._line = this._line.bind(this);
@@ -3195,7 +3206,7 @@ var TextMixin = {
3195
3206
  this.y = y;
3196
3207
  return height;
3197
3208
  },
3198
- list(list, x, y, options, wrapper) {
3209
+ list(list, x, y, options) {
3199
3210
  options = this._initOptions(x, y, options);
3200
3211
  const listType = options.listType || 'bullet';
3201
3212
  const unit = Math.round(this._font.ascender / 1000 * this._fontSize);
@@ -3225,19 +3236,8 @@ var TextMixin = {
3225
3236
  }
3226
3237
  };
3227
3238
  flatten(list);
3228
- const label = function (n) {
3229
- switch (listType) {
3230
- case 'numbered':
3231
- return `${n}.`;
3232
- case 'lettered':
3233
- var letter = String.fromCharCode((n - 1) % 26 + 65);
3234
- var times = Math.floor((n - 1) / 26 + 1);
3235
- var text = Array(times + 1).join(letter);
3236
- return `${text}.`;
3237
- }
3238
- };
3239
3239
  const drawListItem = function (listItem, i) {
3240
- wrapper = new LineWrapper(this, options);
3240
+ const wrapper = new LineWrapper(this, options);
3241
3241
  wrapper.on('line', this._line);
3242
3242
  level = 1;
3243
3243
  wrapper.once('firstLine', () => {
@@ -3272,7 +3272,7 @@ var TextMixin = {
3272
3272
  break;
3273
3273
  case 'numbered':
3274
3274
  case 'lettered':
3275
- var text = label(numbers[i - 1]);
3275
+ var text = formatListLabel(numbers[i - 1], listType);
3276
3276
  this._fragment(text, this.x - indent, this.y, options);
3277
3277
  break;
3278
3278
  }
@@ -3340,11 +3340,11 @@ var TextMixin = {
3340
3340
  },
3341
3341
  _line(text, options = {}, wrapper) {
3342
3342
  this._fragment(text, this.x, this.y, options);
3343
- const lineGap = options.lineGap || this._lineGap || 0;
3344
- if (!wrapper) {
3345
- this.x += this.widthOfString(text, options);
3346
- } else {
3343
+ if (wrapper) {
3344
+ const lineGap = options.lineGap || this._lineGap || 0;
3347
3345
  this.y += this.currentLineHeight(true) + lineGap;
3346
+ } else {
3347
+ this.x += this.widthOfString(text, options);
3348
3348
  }
3349
3349
  },
3350
3350
  _fragment(text, x, y, options) {
@@ -3731,8 +3731,8 @@ class PDFImage {
3731
3731
  } else if (src instanceof ArrayBuffer) {
3732
3732
  data = Buffer.from(new Uint8Array(src));
3733
3733
  } else {
3734
- let match;
3735
- if (match = /^data:.+?;base64,(.*)$/.exec(src)) {
3734
+ const match = /^data:.+?;base64,(.*)$/.exec(src);
3735
+ if (match) {
3736
3736
  data = Buffer.from(match[1], 'base64');
3737
3737
  } else {
3738
3738
  data = fs.readFileSync(src);
@@ -4819,8 +4819,8 @@ var AttachmentsMixin = {
4819
4819
  } else if (src instanceof ArrayBuffer) {
4820
4820
  data = Buffer.from(new Uint8Array(src));
4821
4821
  } else {
4822
- let match;
4823
- if (match = /^data:(.*?);base64,(.*)$/.exec(src)) {
4822
+ const match = /^data:(.*?);base64,(.*)$/.exec(src);
4823
+ if (match) {
4824
4824
  if (match[1]) {
4825
4825
  refBody.Subtype = match[1].replace('/', '#2F');
4826
4826
  }
@@ -5017,7 +5017,7 @@ function deepMerge(target, ...sources) {
5017
5017
  }
5018
5018
  function deepClone(obj) {
5019
5019
  let result = obj;
5020
- if (typeof obj == 'object') {
5020
+ if (obj && typeof obj == 'object') {
5021
5021
  result = Array.isArray(obj) ? [] : {};
5022
5022
  for (const key in obj) result[key] = deepClone(obj[key]);
5023
5023
  }