pdf-parser.js 5.2.27 → 5.2.28

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.
Files changed (145) hide show
  1. package/dist/{afm-widths-BYiX2L9D.cjs → afm-widths-BHD2HZIL.cjs} +553 -642
  2. package/dist/{afm-widths-blUDDjlI.js → afm-widths-B_IGbGky.js} +553 -642
  3. package/dist/afm-widths.cjs +1 -1
  4. package/dist/afm-widths.js +1 -1
  5. package/dist/annotations.cjs +5 -3
  6. package/dist/annotations.js +5 -3
  7. package/dist/builtin-encoding.cjs +17 -6
  8. package/dist/builtin-encoding.js +17 -6
  9. package/dist/bytes/crc32.cjs +5 -3
  10. package/dist/bytes/crc32.js +5 -3
  11. package/dist/bytes/flate.cjs +0 -1
  12. package/dist/bytes/flate.js +0 -1
  13. package/dist/cff-bounds.cjs +42 -24
  14. package/dist/cff-bounds.js +42 -24
  15. package/dist/cff.cjs +13 -6
  16. package/dist/cff.js +13 -6
  17. package/dist/cmap-table.cjs +54 -26
  18. package/dist/cmap-table.js +54 -26
  19. package/dist/cmap.cjs +5 -3
  20. package/dist/cmap.js +5 -3
  21. package/dist/content-write.cjs +3 -2
  22. package/dist/content-write.js +3 -2
  23. package/dist/crypto/aes.cjs +76 -55
  24. package/dist/crypto/aes.js +76 -55
  25. package/dist/crypto/md5.cjs +345 -149
  26. package/dist/crypto/md5.js +345 -149
  27. package/dist/crypto/rc4.cjs +5 -4
  28. package/dist/crypto/rc4.js +5 -4
  29. package/dist/crypto/sha2.cjs +92 -43
  30. package/dist/crypto/sha2.js +92 -43
  31. package/dist/embedded-font.cjs +4 -2
  32. package/dist/embedded-font.js +4 -2
  33. package/dist/encoding.cjs +1 -1
  34. package/dist/encoding.js +1 -1
  35. package/dist/encrypt-write.cjs +25 -21
  36. package/dist/encrypt-write.js +25 -21
  37. package/dist/encrypt.cjs +43 -64
  38. package/dist/encrypt.js +43 -64
  39. package/dist/filters.cjs +40 -20
  40. package/dist/filters.js +40 -20
  41. package/dist/font-face.cjs +2 -1
  42. package/dist/font-face.js +2 -1
  43. package/dist/font-read.cjs +12 -6
  44. package/dist/font-read.js +12 -6
  45. package/dist/font-tables.cjs +55 -28
  46. package/dist/font-tables.js +55 -28
  47. package/dist/gdef-table.cjs +6 -3
  48. package/dist/gdef-table.js +6 -3
  49. package/dist/glyf-contours.cjs +3 -1
  50. package/dist/glyf-contours.js +3 -1
  51. package/dist/glyf.cjs +22 -11
  52. package/dist/glyf.js +22 -11
  53. package/dist/gpos-table.cjs +37 -19
  54. package/dist/gpos-table.js +37 -19
  55. package/dist/gsub-table.cjs +28 -17
  56. package/dist/gsub-table.js +28 -17
  57. package/dist/hmtx-table.cjs +5 -3
  58. package/dist/hmtx-table.js +5 -3
  59. package/dist/image/ccitt-encode.cjs +8 -5
  60. package/dist/image/ccitt-encode.js +8 -5
  61. package/dist/image/ccitt.cjs +801 -209
  62. package/dist/image/ccitt.js +801 -209
  63. package/dist/image/jbig2-arith.cjs +340 -306
  64. package/dist/image/jbig2-arith.js +340 -306
  65. package/dist/image/jbig2-bitmap.cjs +8 -5
  66. package/dist/image/jbig2-bitmap.js +8 -5
  67. package/dist/image/jbig2-generic.cjs +240 -69
  68. package/dist/image/jbig2-generic.js +240 -69
  69. package/dist/image/jbig2-text.cjs +4 -2
  70. package/dist/image/jbig2-text.js +4 -2
  71. package/dist/image/jbig2.cjs +69 -31
  72. package/dist/image/jbig2.js +69 -31
  73. package/dist/image/jp2-boxes.cjs +52 -27
  74. package/dist/image/jp2-boxes.js +52 -27
  75. package/dist/image/jpeg-info.cjs +29 -24
  76. package/dist/image/jpeg-info.js +29 -24
  77. package/dist/image/jpeg2000-codestream.cjs +44 -24
  78. package/dist/image/jpeg2000-codestream.js +44 -24
  79. package/dist/image/jpeg2000-dwt.cjs +2 -1
  80. package/dist/image/jpeg2000-dwt.js +2 -1
  81. package/dist/image/jpeg2000-t1.cjs +21 -11
  82. package/dist/image/jpeg2000-t1.js +21 -11
  83. package/dist/image/jpeg2000-t2.cjs +12 -5
  84. package/dist/image/jpeg2000-t2.js +12 -5
  85. package/dist/image/jpeg2000-tagtree.cjs +8 -4
  86. package/dist/image/jpeg2000-tagtree.js +8 -4
  87. package/dist/image/jpeg2000.cjs +11 -6
  88. package/dist/image/jpeg2000.js +11 -6
  89. package/dist/image/png-decode.cjs +62 -39
  90. package/dist/image/png-decode.d.cts +3 -2
  91. package/dist/image/png-decode.d.ts +3 -2
  92. package/dist/image/png-decode.js +62 -39
  93. package/dist/image/png-filter.cjs +23 -15
  94. package/dist/image/png-filter.js +23 -15
  95. package/dist/images-read.cjs +41 -36
  96. package/dist/images-read.js +41 -36
  97. package/dist/index.cjs +1 -1
  98. package/dist/index.js +1 -1
  99. package/dist/interpret.cjs +39 -24
  100. package/dist/interpret.js +39 -24
  101. package/dist/lexer.cjs +86 -51
  102. package/dist/lexer.js +86 -51
  103. package/dist/math-content-write.cjs +9 -5
  104. package/dist/math-content-write.js +9 -5
  105. package/dist/math-font-write.cjs +2 -1
  106. package/dist/math-font-write.js +2 -1
  107. package/dist/math-font.cjs +16 -7
  108. package/dist/math-font.js +16 -7
  109. package/dist/math-table.cjs +25 -13
  110. package/dist/math-table.js +25 -13
  111. package/dist/matrix.cjs +3 -2
  112. package/dist/matrix.js +3 -2
  113. package/dist/measure.cjs +1 -1
  114. package/dist/measure.js +1 -1
  115. package/dist/navigation.cjs +10 -5
  116. package/dist/navigation.js +10 -5
  117. package/dist/ot-layout-common.cjs +4 -2
  118. package/dist/ot-layout-common.js +4 -2
  119. package/dist/parse.cjs +7 -5
  120. package/dist/parse.js +7 -5
  121. package/dist/pdf-text.cjs +5 -2
  122. package/dist/pdf-text.js +5 -2
  123. package/dist/predictors.cjs +14 -9
  124. package/dist/predictors.js +14 -9
  125. package/dist/raster.cjs +30 -19
  126. package/dist/raster.js +30 -19
  127. package/dist/read.cjs +17 -8
  128. package/dist/read.js +17 -8
  129. package/dist/serialize.cjs +6 -2
  130. package/dist/serialize.js +6 -2
  131. package/dist/sfnt-subset.cjs +25 -13
  132. package/dist/sfnt-subset.js +25 -13
  133. package/dist/sfnt.cjs +20 -10
  134. package/dist/sfnt.js +20 -10
  135. package/dist/text-group.cjs +0 -1
  136. package/dist/text-group.js +0 -1
  137. package/dist/tounicode.cjs +4 -2
  138. package/dist/tounicode.js +4 -2
  139. package/dist/winansi.cjs +1 -1
  140. package/dist/winansi.js +1 -1
  141. package/dist/write.cjs +20 -12
  142. package/dist/write.js +20 -12
  143. package/dist/xref.cjs +5 -2
  144. package/dist/xref.js +5 -2
  145. package/package.json +1 -1
@@ -3,10 +3,14 @@ import { decodeStream } from "./filters.js";
3
3
  import { decodeJpeg2000 } from "./image/jpeg2000.js";
4
4
  import { PNG_MAX_DIMENSION, PNG_MAX_PIXELS, encodePng, readJpegInfo } from "byte-codec";
5
5
  //#region src/images-read.ts
6
+ const CMYK_COMPONENT_COUNT = 4;
7
+ const RGB_CHANNEL_COUNT = 3;
8
+ const MAX_BYTE_VALUE = 255;
9
+ const BITS_PER_BYTE = 8;
6
10
  function componentsOf(cs) {
7
11
  if (cs.kind === "gray") return 1;
8
- if (cs.kind === "cmyk") return 4;
9
- return 3;
12
+ if (cs.kind === "cmyk") return CMYK_COMPONENT_COUNT;
13
+ return RGB_CHANNEL_COUNT;
10
14
  }
11
15
  function resolveColorSpace(csObj, resolver, sink) {
12
16
  const resolved = resolver.resolve(csObj);
@@ -30,7 +34,7 @@ function resolveColorSpace(csObj, resolver, sink) {
30
34
  const streamObj = resolver.resolve(arr[1]);
31
35
  const n = streamObj?.kind === "stream" ? asNumber(dictGet(streamObj.dict, "N")) : void 0;
32
36
  if (n === 1) return { kind: "gray" };
33
- if (n === 4) return { kind: "cmyk" };
37
+ if (n === CMYK_COMPONENT_COUNT) return { kind: "cmyk" };
34
38
  return { kind: "rgb" };
35
39
  }
36
40
  if (family === "Indexed") {
@@ -54,9 +58,9 @@ function resolveColorSpace(csObj, resolver, sink) {
54
58
  };
55
59
  }
56
60
  function unpackSamples(data, width, height, componentsPerPixel, bitsPerComponent) {
57
- if (bitsPerComponent === 8) return Array.from(data.subarray(0, width * height * componentsPerPixel));
61
+ if (bitsPerComponent === BITS_PER_BYTE) return Array.from(data.subarray(0, width * height * componentsPerPixel));
58
62
  const samplesPerRow = width * componentsPerPixel;
59
- const bytesPerRow = Math.ceil(samplesPerRow * bitsPerComponent / 8);
63
+ const bytesPerRow = Math.ceil(samplesPerRow * bitsPerComponent / BITS_PER_BYTE);
60
64
  const out = [];
61
65
  for (let row = 0; row < height; row++) {
62
66
  const rowStart = row * bytesPerRow;
@@ -64,8 +68,8 @@ function unpackSamples(data, width, height, componentsPerPixel, bitsPerComponent
64
68
  for (let s = 0; s < samplesPerRow; s++) {
65
69
  let value = 0;
66
70
  for (let b = 0; b < bitsPerComponent; b++) {
67
- const byteIndex = rowStart + Math.floor(bitPos / 8);
68
- const bitIndex = 7 - bitPos % 8;
71
+ const byteIndex = rowStart + Math.floor(bitPos / BITS_PER_BYTE);
72
+ const bitIndex = 7 - bitPos % BITS_PER_BYTE;
69
73
  const bit = (data[byteIndex] ?? 0) >> bitIndex & 1;
70
74
  value = value << 1 | bit;
71
75
  bitPos++;
@@ -77,13 +81,13 @@ function unpackSamples(data, width, height, componentsPerPixel, bitsPerComponent
77
81
  }
78
82
  function scaleToByte(value, maxValue, inverted) {
79
83
  const v = inverted ? maxValue - value : value;
80
- return maxValue === 255 ? v : Math.round(v * 255 / maxValue);
84
+ return maxValue === MAX_BYTE_VALUE ? v : Math.round(v * MAX_BYTE_VALUE / maxValue);
81
85
  }
82
86
  function cmykToRgbByte(c, m, y, k) {
83
87
  return {
84
- r: Math.round(255 * (1 - c) * (1 - k)),
85
- g: Math.round(255 * (1 - m) * (1 - k)),
86
- b: Math.round(255 * (1 - y) * (1 - k))
88
+ r: Math.round(MAX_BYTE_VALUE * (1 - c) * (1 - k)),
89
+ g: Math.round(MAX_BYTE_VALUE * (1 - m) * (1 - k)),
90
+ b: Math.round(MAX_BYTE_VALUE * (1 - y) * (1 - k))
87
91
  };
88
92
  }
89
93
  function sampleFromPalette(base, lookup, offset) {
@@ -95,7 +99,7 @@ function sampleFromPalette(base, lookup, offset) {
95
99
  b: g
96
100
  };
97
101
  }
98
- if (base.kind === "cmyk") return cmykToRgbByte((lookup[offset] ?? 0) / 255, (lookup[offset + 1] ?? 0) / 255, (lookup[offset + 2] ?? 0) / 255, (lookup[offset + 3] ?? 0) / 255);
102
+ if (base.kind === "cmyk") return cmykToRgbByte((lookup[offset] ?? 0) / MAX_BYTE_VALUE, (lookup[offset + 1] ?? 0) / MAX_BYTE_VALUE, (lookup[offset + 2] ?? 0) / MAX_BYTE_VALUE, (lookup[offset + 3] ?? 0) / MAX_BYTE_VALUE);
99
103
  return {
100
104
  r: lookup[offset] ?? 0,
101
105
  g: lookup[offset + 1] ?? 0,
@@ -107,7 +111,7 @@ function buildRawImage(data, width, height, bitsPerComponent, colorSpace, invert
107
111
  if (colorSpace.kind === "indexed") {
108
112
  const indices = unpackSamples(data, width, height, 1, bitsPerComponent);
109
113
  const baseComponents = componentsOf(colorSpace.base);
110
- const out = new Uint8Array(width * height * (colorSpace.base.kind === "gray" ? 1 : 3));
114
+ const out = new Uint8Array(width * height * (colorSpace.base.kind === "gray" ? 1 : RGB_CHANNEL_COUNT));
111
115
  let outIdx = 0;
112
116
  for (const index of indices) {
113
117
  const rgb = sampleFromPalette(colorSpace.base, colorSpace.lookup, index * baseComponents);
@@ -121,7 +125,7 @@ function buildRawImage(data, width, height, bitsPerComponent, colorSpace, invert
121
125
  return {
122
126
  width,
123
127
  height,
124
- channels: colorSpace.base.kind === "gray" ? 1 : 3,
128
+ channels: colorSpace.base.kind === "gray" ? 1 : RGB_CHANNEL_COUNT,
125
129
  data: out
126
130
  };
127
131
  }
@@ -135,26 +139,27 @@ function buildRawImage(data, width, height, bitsPerComponent, colorSpace, invert
135
139
  };
136
140
  }
137
141
  if (colorSpace.kind === "rgb") {
138
- const samples = unpackSamples(data, width, height, 3, bitsPerComponent);
142
+ const samples = unpackSamples(data, width, height, RGB_CHANNEL_COUNT, bitsPerComponent);
143
+ const out = Uint8Array.from(samples, (v) => scaleToByte(v, maxValue, inverted));
139
144
  return {
140
145
  width,
141
146
  height,
142
- channels: 3,
143
- data: Uint8Array.from(samples, (v) => scaleToByte(v, maxValue, inverted))
147
+ channels: RGB_CHANNEL_COUNT,
148
+ data: out
144
149
  };
145
150
  }
146
- const samples = unpackSamples(data, width, height, 4, bitsPerComponent);
147
- const out = new Uint8Array(width * height * 3);
151
+ const samples = unpackSamples(data, width, height, CMYK_COMPONENT_COUNT, bitsPerComponent);
152
+ const out = new Uint8Array(width * height * RGB_CHANNEL_COUNT);
148
153
  for (let px = 0; px < width * height; px++) {
149
- const rgb = cmykToRgbByte(scaleToByte(samples[px * 4] ?? 0, maxValue, inverted) / 255, scaleToByte(samples[px * 4 + 1] ?? 0, maxValue, inverted) / 255, scaleToByte(samples[px * 4 + 2] ?? 0, maxValue, inverted) / 255, scaleToByte(samples[px * 4 + 3] ?? 0, maxValue, inverted) / 255);
150
- out[px * 3] = rgb.r;
151
- out[px * 3 + 1] = rgb.g;
152
- out[px * 3 + 2] = rgb.b;
154
+ const rgb = cmykToRgbByte(scaleToByte(samples[px * CMYK_COMPONENT_COUNT] ?? 0, maxValue, inverted) / MAX_BYTE_VALUE, scaleToByte(samples[px * CMYK_COMPONENT_COUNT + 1] ?? 0, maxValue, inverted) / MAX_BYTE_VALUE, scaleToByte(samples[px * CMYK_COMPONENT_COUNT + 2] ?? 0, maxValue, inverted) / MAX_BYTE_VALUE, scaleToByte(samples[px * CMYK_COMPONENT_COUNT + 3] ?? 0, maxValue, inverted) / MAX_BYTE_VALUE);
155
+ out[px * RGB_CHANNEL_COUNT] = rgb.r;
156
+ out[px * RGB_CHANNEL_COUNT + 1] = rgb.g;
157
+ out[px * RGB_CHANNEL_COUNT + 2] = rgb.b;
153
158
  }
154
159
  return {
155
160
  width,
156
161
  height,
157
- channels: 3,
162
+ channels: RGB_CHANNEL_COUNT,
158
163
  data: out
159
164
  };
160
165
  }
@@ -165,8 +170,8 @@ function readSoftMaskAlpha(dict, width, height, resolver, sink) {
165
170
  if (decoded.remainingFilter !== void 0) return;
166
171
  const smaskWidth = asNumber(dictGet(smaskObj.dict, "Width")) ?? width;
167
172
  const smaskHeight = asNumber(dictGet(smaskObj.dict, "Height")) ?? height;
168
- const smaskBpc = asNumber(dictGet(smaskObj.dict, "BitsPerComponent")) ?? 8;
169
- if (smaskWidth !== width || smaskHeight !== height || smaskBpc !== 8) return;
173
+ const smaskBpc = asNumber(dictGet(smaskObj.dict, "BitsPerComponent")) ?? BITS_PER_BYTE;
174
+ if (smaskWidth !== width || smaskHeight !== height || smaskBpc !== BITS_PER_BYTE) return;
170
175
  return decoded.bytes.subarray(0, width * height);
171
176
  }
172
177
  function jpeg2000ChannelKind(image, dict, resolver, sink) {
@@ -178,7 +183,7 @@ function jpeg2000ChannelKind(image, dict, resolver, sink) {
178
183
  if (image.colourSpace === "greyscale") return "gray";
179
184
  if (image.colourSpace === "cmyk") return "cmyk";
180
185
  if (image.colourSpace === "srgb" || image.colourSpace === "sycc" || image.colourSpace === "e-srgb" || image.colourSpace === "rommrgb") return "rgb";
181
- return image.components.length >= 4 ? "cmyk" : image.components.length >= 3 ? "rgb" : "gray";
186
+ return image.components.length >= CMYK_COMPONENT_COUNT ? "cmyk" : image.components.length >= RGB_CHANNEL_COUNT ? "rgb" : "gray";
182
187
  }
183
188
  function readJpeg2000Image(dict, raw, resolver, sink) {
184
189
  let image;
@@ -204,7 +209,7 @@ function readJpeg2000Image(dict, raw, resolver, sink) {
204
209
  return;
205
210
  }
206
211
  const kind = jpeg2000ChannelKind(image, dict, resolver, sink);
207
- const required = kind === "cmyk" ? 4 : kind === "rgb" ? 3 : 1;
212
+ const required = kind === "cmyk" ? CMYK_COMPONENT_COUNT : kind === "rgb" ? RGB_CHANNEL_COUNT : 1;
208
213
  if (image.components.length < required) {
209
214
  sink({
210
215
  code: "image/jpx-undecodable",
@@ -219,15 +224,15 @@ function readJpeg2000Image(dict, raw, resolver, sink) {
219
224
  message: `JPXDecode image carries ${String(image.components.length)} components where its colour space needs ${String(required)}; the extra channel(s) are ignored`
220
225
  });
221
226
  const maximum = (1 << image.bitDepth) - 1;
222
- const scale = (value) => image.bitDepth === 8 ? value : Math.round(value * 255 / maximum);
227
+ const scale = (value) => image.bitDepth === BITS_PER_BYTE ? value : Math.round(value * MAX_BYTE_VALUE / maximum);
223
228
  const pixels = image.width * image.height;
224
- const channels = kind === "gray" ? 1 : 3;
229
+ const channels = kind === "gray" ? 1 : RGB_CHANNEL_COUNT;
225
230
  const data = new Uint8Array(pixels * channels);
226
231
  if (kind === "cmyk") for (let i = 0; i < pixels; i++) {
227
- const rgb = cmykToRgbByte(scale(image.components[0]?.[i] ?? 0) / 255, scale(image.components[1]?.[i] ?? 0) / 255, scale(image.components[2]?.[i] ?? 0) / 255, scale(image.components[3]?.[i] ?? 0) / 255);
228
- data[i * 3] = rgb.r;
229
- data[i * 3 + 1] = rgb.g;
230
- data[i * 3 + 2] = rgb.b;
232
+ const rgb = cmykToRgbByte(scale(image.components[0]?.[i] ?? 0) / MAX_BYTE_VALUE, scale(image.components[1]?.[i] ?? 0) / MAX_BYTE_VALUE, scale(image.components[2]?.[i] ?? 0) / MAX_BYTE_VALUE, scale(image.components[3]?.[i] ?? 0) / MAX_BYTE_VALUE);
233
+ data[i * RGB_CHANNEL_COUNT] = rgb.r;
234
+ data[i * RGB_CHANNEL_COUNT + 1] = rgb.g;
235
+ data[i * RGB_CHANNEL_COUNT + 2] = rgb.b;
231
236
  }
232
237
  else for (let channel = 0; channel < channels; channel++) {
233
238
  const plane = image.components[channel];
@@ -301,8 +306,8 @@ function readImageXObject(dict, raw, resolver, sink) {
301
306
  });
302
307
  return;
303
308
  }
304
- const bitsPerComponent = asNumber(dictGet(dict, "BitsPerComponent") ?? dictGet(dict, "BPC")) ?? 8;
305
- if (bitsPerComponent !== 1 && bitsPerComponent !== 2 && bitsPerComponent !== 4 && bitsPerComponent !== 8) {
309
+ const bitsPerComponent = asNumber(dictGet(dict, "BitsPerComponent") ?? dictGet(dict, "BPC")) ?? BITS_PER_BYTE;
310
+ if (bitsPerComponent !== 1 && bitsPerComponent !== 2 && bitsPerComponent !== 4 && bitsPerComponent !== BITS_PER_BYTE) {
306
311
  sink({
307
312
  code: "image/unsupported-bit-depth",
308
313
  severity: "warning",
package/dist/index.cjs CHANGED
@@ -1,5 +1,5 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
- const require_afm_widths = require("./afm-widths-BYiX2L9D.cjs");
2
+ const require_afm_widths = require("./afm-widths-BHD2HZIL.cjs");
3
3
  const require_image_ccitt = require("./image/ccitt.cjs");
4
4
  const require_image_jbig2_errors = require("./image/jbig2-errors.cjs");
5
5
  const require_image_jbig2 = require("./image/jbig2.cjs");
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
- import { t as STANDARD_METRICS } from "./afm-widths-blUDDjlI.js";
1
+ import { t as STANDARD_METRICS } from "./afm-widths-B_IGbGky.js";
2
2
  import { decodeCcittFax } from "./image/ccitt.js";
3
3
  import { Jbig2ParseError, Jbig2UnsupportedError } from "./image/jbig2-errors.js";
4
4
  import { decodeJbig2Embedded } from "./image/jbig2.js";
@@ -8,6 +8,8 @@ let document_schema_js = require("document-schema.js");
8
8
  //#region src/interpret.ts
9
9
  const MAX_FORM_XOBJECT_DEPTH = 12;
10
10
  const FALLBACK_GLYPH_WIDTH_PER_1000 = 500;
11
+ const GLYPH_SPACE_PER_TEXT_SPACE_UNIT = 1e3;
12
+ const ASCII_SPACE = 32;
11
13
  const DEFAULT_LINE_WIDTH_PT = 1;
12
14
  function initialTextParameters() {
13
15
  return {
@@ -72,31 +74,37 @@ function rgbColor(operands) {
72
74
  b: numAt(operands, 2)
73
75
  };
74
76
  }
77
+ const CMYK_K_INDEX = 3;
75
78
  function cmykColor(operands) {
76
79
  const c = numAt(operands, 0);
77
80
  const m = numAt(operands, 1);
78
81
  const y = numAt(operands, 2);
79
- const k = numAt(operands, 3);
82
+ const k = numAt(operands, CMYK_K_INDEX);
80
83
  return {
81
84
  r: (1 - c) * (1 - k),
82
85
  g: (1 - m) * (1 - k),
83
86
  b: (1 - y) * (1 - k)
84
87
  };
85
88
  }
89
+ const RGB_COMPONENT_COUNT = 3;
90
+ const CMYK_COMPONENT_COUNT = 4;
86
91
  function genericColor(operands) {
87
92
  const numericOperands = operands.filter((o) => o.kind === "number");
88
93
  if (numericOperands.length === 1) return grayColor(numAt(numericOperands, 0));
89
- if (numericOperands.length === 3) return rgbColor(numericOperands);
90
- if (numericOperands.length === 4) return cmykColor(numericOperands);
94
+ if (numericOperands.length === RGB_COMPONENT_COUNT) return rgbColor(numericOperands);
95
+ if (numericOperands.length === CMYK_COMPONENT_COUNT) return cmykColor(numericOperands);
91
96
  }
97
+ const MATRIX_D_INDEX = 3;
98
+ const MATRIX_E_INDEX = 4;
99
+ const MATRIX_F_INDEX = 5;
92
100
  function matrixFromOperands(operands) {
93
101
  return [
94
102
  numAt(operands, 0),
95
103
  numAt(operands, 1),
96
104
  numAt(operands, 2),
97
- numAt(operands, 3),
98
- numAt(operands, 4),
99
- numAt(operands, 5)
105
+ numAt(operands, MATRIX_D_INDEX),
106
+ numAt(operands, MATRIX_E_INDEX),
107
+ numAt(operands, MATRIX_F_INDEX)
100
108
  ];
101
109
  }
102
110
  const SHAPE_ABS_TOLERANCE_PT = .001;
@@ -140,9 +148,10 @@ function closedPolygonCorners(subpath) {
140
148
  if (nearlyEqualPoints(first, last, shapeTolerance(Math.max(bounds.maxX - bounds.minX, bounds.maxY - bounds.minY)))) corners.pop();
141
149
  return corners;
142
150
  }
151
+ const RECTANGLE_CORNER_COUNT = 4;
143
152
  function detectRect(subpath, paint) {
144
153
  const corners = closedPolygonCorners(subpath);
145
- if (corners?.length !== 4) return;
154
+ if (corners?.length !== RECTANGLE_CORNER_COUNT) return;
146
155
  const { minX, minY, maxX, maxY } = boundsOf(corners);
147
156
  const widthPt = maxX - minX;
148
157
  const heightPt = maxY - minY;
@@ -190,9 +199,10 @@ function expectedEllipseControl(atExtreme, atExtremeKind, otherEnd, center, kx,
190
199
  y: atExtreme.y
191
200
  };
192
201
  }
202
+ const ELLIPSE_SEGMENT_COUNT = 4;
193
203
  function detectEllipse(subpath, paint) {
194
204
  const segments = subpath.segments;
195
- if (!subpath.closed || segments.length !== 4 || segments.some((segment) => segment.kind !== "cubic")) return;
205
+ if (!subpath.closed || segments.length !== ELLIPSE_SEGMENT_COUNT || segments.some((segment) => segment.kind !== "cubic")) return;
196
206
  const start = {
197
207
  x: subpath.startXPt,
198
208
  y: subpath.startYPt
@@ -218,16 +228,16 @@ function detectEllipse(subpath, paint) {
218
228
  y: finalSegment.yPt
219
229
  }, start, Math.max(tolX, tolY))) return;
220
230
  const extremes = onCurve.map((point) => cardinalExtremeOf(point, center, rx, ry, tolX, tolY));
221
- if (extremes.some((extreme) => extreme === void 0) || new Set(extremes).size !== 4) return;
231
+ if (extremes.some((extreme) => extreme === void 0) || new Set(extremes).size !== ELLIPSE_SEGMENT_COUNT) return;
222
232
  const kx = rx * require_matrix.BEZIER_KAPPA;
223
233
  const ky = ry * require_matrix.BEZIER_KAPPA;
224
234
  const controlTolerance = Math.max(tolX, tolY);
225
- for (let i = 0; i < 4; i += 1) {
235
+ for (let i = 0; i < ELLIPSE_SEGMENT_COUNT; i += 1) {
226
236
  const segment = segments[i];
227
237
  const from = onCurve[i];
228
238
  const fromKind = extremes[i];
229
- const to = onCurve[(i + 1) % 4];
230
- const toKind = extremes[(i + 1) % 4];
239
+ const to = onCurve[(i + 1) % ELLIPSE_SEGMENT_COUNT];
240
+ const toKind = extremes[(i + 1) % ELLIPSE_SEGMENT_COUNT];
231
241
  if (segment?.kind !== "cubic" || from === void 0 || to === void 0 || fromKind === void 0 || toKind === void 0) return;
232
242
  const expectedC1 = expectedEllipseControl(from, fromKind, to, center, kx, ky);
233
243
  const expectedC2 = expectedEllipseControl(to, toKind, from, center, kx, ky);
@@ -292,6 +302,11 @@ var MarkedContentStack = class {
292
302
  }
293
303
  }
294
304
  };
305
+ const RE_HEIGHT_INDEX = 3;
306
+ const OPERAND_INDEX_3 = 3;
307
+ const OPERAND_INDEX_4 = 4;
308
+ const OPERAND_INDEX_5 = 5;
309
+ const TZ_PERCENT_DIVISOR = 100;
295
310
  function interpretContentStream(bytes, resources, context) {
296
311
  return runContentStream(bytes, resources, {
297
312
  ctm: require_matrix.IDENTITY_MATRIX,
@@ -362,7 +377,7 @@ function runContentStream(bytes, resources, initialState, context, depth, marked
362
377
  const x = numAt(operands, 0);
363
378
  const y = numAt(operands, 1);
364
379
  const w = numAt(operands, 2);
365
- const h = numAt(operands, 3);
380
+ const h = numAt(operands, RE_HEIGHT_INDEX);
366
381
  const p1 = require_matrix.applyMatrix(ctm, {
367
382
  x,
368
383
  y
@@ -444,10 +459,10 @@ function runContentStream(bytes, resources, initialState, context, depth, marked
444
459
  });
445
460
  const widthPer1000 = glyph?.widthPer1000 ?? FALLBACK_GLYPH_WIDTH_PER_1000;
446
461
  const byteLength = glyph?.byteLengthConsumed ?? 1;
447
- const isSingleByteSpace = byteLength === 1 && codes[offset] === 32;
462
+ const isSingleByteSpace = byteLength === 1 && codes[offset] === ASCII_SPACE;
448
463
  const spacing = gs.charSpace + (isSingleByteSpace ? gs.wordSpace : 0);
449
464
  const vertical = glyph?.vertical;
450
- text.tm = vertical === void 0 ? require_matrix.multiplyMatrices(require_matrix.translationMatrix((widthPer1000 / 1e3 * gs.fontSizePt + spacing) * gs.horizScale, 0), text.tm) : require_matrix.multiplyMatrices(require_matrix.translationMatrix(0, vertical.displacementPer1000 / 1e3 * gs.fontSizePt + spacing), text.tm);
465
+ text.tm = vertical === void 0 ? require_matrix.multiplyMatrices(require_matrix.translationMatrix((widthPer1000 / GLYPH_SPACE_PER_TEXT_SPACE_UNIT * gs.fontSizePt + spacing) * gs.horizScale, 0), text.tm) : require_matrix.multiplyMatrices(require_matrix.translationMatrix(0, vertical.displacementPer1000 / GLYPH_SPACE_PER_TEXT_SPACE_UNIT * gs.fontSizePt + spacing), text.tm);
451
466
  offset += byteLength;
452
467
  }
453
468
  };
@@ -457,8 +472,8 @@ function runContentStream(bytes, resources, initialState, context, depth, marked
457
472
  const vertical = context.fontMetrics.glyphAdvance(fontResourceName, resources, codes, 0)?.vertical;
458
473
  if (vertical === void 0) return;
459
474
  return {
460
- x: vertical.positionXPer1000 / 1e3,
461
- y: vertical.positionYPer1000 / 1e3
475
+ x: vertical.positionXPer1000 / GLYPH_SPACE_PER_TEXT_SPACE_UNIT,
476
+ y: vertical.positionYPer1000 / GLYPH_SPACE_PER_TEXT_SPACE_UNIT
462
477
  };
463
478
  };
464
479
  const showTextArray = (elements) => {
@@ -475,7 +490,7 @@ function runContentStream(bytes, resources, initialState, context, depth, marked
475
490
  totalLength += el.bytes.length;
476
491
  advanceThroughString(el.bytes);
477
492
  } else if (el.kind === "number") {
478
- const adjustment = -(el.value / 1e3) * gs.fontSizePt;
493
+ const adjustment = -(el.value / GLYPH_SPACE_PER_TEXT_SPACE_UNIT) * gs.fontSizePt;
479
494
  text.tm = require_matrix.multiplyMatrices(vertical ? require_matrix.translationMatrix(0, adjustment) : require_matrix.translationMatrix(adjustment * gs.horizScale, 0), text.tm);
480
495
  }
481
496
  if (totalLength === 0) return;
@@ -673,11 +688,11 @@ function runContentStream(bytes, resources, initialState, context, depth, marked
673
688
  });
674
689
  const c2 = require_matrix.applyMatrix(gs.ctm, {
675
690
  x: numAt(operands, 2),
676
- y: numAt(operands, 3)
691
+ y: numAt(operands, OPERAND_INDEX_3)
677
692
  });
678
693
  const p = require_matrix.applyMatrix(gs.ctm, {
679
- x: numAt(operands, 4),
680
- y: numAt(operands, 5)
694
+ x: numAt(operands, OPERAND_INDEX_4),
695
+ y: numAt(operands, OPERAND_INDEX_5)
681
696
  });
682
697
  currentSubpath?.segments.push({
683
698
  kind: "cubic",
@@ -699,7 +714,7 @@ function runContentStream(bytes, resources, initialState, context, depth, marked
699
714
  });
700
715
  const p = require_matrix.applyMatrix(gs.ctm, {
701
716
  x: numAt(operands, 2),
702
- y: numAt(operands, 3)
717
+ y: numAt(operands, OPERAND_INDEX_3)
703
718
  });
704
719
  currentSubpath.segments.push({
705
720
  kind: "cubic",
@@ -719,7 +734,7 @@ function runContentStream(bytes, resources, initialState, context, depth, marked
719
734
  });
720
735
  const p = require_matrix.applyMatrix(gs.ctm, {
721
736
  x: numAt(operands, 2),
722
- y: numAt(operands, 3)
737
+ y: numAt(operands, OPERAND_INDEX_3)
723
738
  });
724
739
  currentSubpath?.segments.push({
725
740
  kind: "cubic",
@@ -784,7 +799,7 @@ function runContentStream(bytes, resources, initialState, context, depth, marked
784
799
  case "Tz":
785
800
  gs = {
786
801
  ...gs,
787
- horizScale: numAt(operands, 0) / 100
802
+ horizScale: numAt(operands, 0) / TZ_PERCENT_DIVISOR
788
803
  };
789
804
  break;
790
805
  case "TL":
package/dist/interpret.js CHANGED
@@ -7,6 +7,8 @@ import { COLOR_BLACK } from "document-schema.js";
7
7
  //#region src/interpret.ts
8
8
  const MAX_FORM_XOBJECT_DEPTH = 12;
9
9
  const FALLBACK_GLYPH_WIDTH_PER_1000 = 500;
10
+ const GLYPH_SPACE_PER_TEXT_SPACE_UNIT = 1e3;
11
+ const ASCII_SPACE = 32;
10
12
  const DEFAULT_LINE_WIDTH_PT = 1;
11
13
  function initialTextParameters() {
12
14
  return {
@@ -71,31 +73,37 @@ function rgbColor(operands) {
71
73
  b: numAt(operands, 2)
72
74
  };
73
75
  }
76
+ const CMYK_K_INDEX = 3;
74
77
  function cmykColor(operands) {
75
78
  const c = numAt(operands, 0);
76
79
  const m = numAt(operands, 1);
77
80
  const y = numAt(operands, 2);
78
- const k = numAt(operands, 3);
81
+ const k = numAt(operands, CMYK_K_INDEX);
79
82
  return {
80
83
  r: (1 - c) * (1 - k),
81
84
  g: (1 - m) * (1 - k),
82
85
  b: (1 - y) * (1 - k)
83
86
  };
84
87
  }
88
+ const RGB_COMPONENT_COUNT = 3;
89
+ const CMYK_COMPONENT_COUNT = 4;
85
90
  function genericColor(operands) {
86
91
  const numericOperands = operands.filter((o) => o.kind === "number");
87
92
  if (numericOperands.length === 1) return grayColor(numAt(numericOperands, 0));
88
- if (numericOperands.length === 3) return rgbColor(numericOperands);
89
- if (numericOperands.length === 4) return cmykColor(numericOperands);
93
+ if (numericOperands.length === RGB_COMPONENT_COUNT) return rgbColor(numericOperands);
94
+ if (numericOperands.length === CMYK_COMPONENT_COUNT) return cmykColor(numericOperands);
90
95
  }
96
+ const MATRIX_D_INDEX = 3;
97
+ const MATRIX_E_INDEX = 4;
98
+ const MATRIX_F_INDEX = 5;
91
99
  function matrixFromOperands(operands) {
92
100
  return [
93
101
  numAt(operands, 0),
94
102
  numAt(operands, 1),
95
103
  numAt(operands, 2),
96
- numAt(operands, 3),
97
- numAt(operands, 4),
98
- numAt(operands, 5)
104
+ numAt(operands, MATRIX_D_INDEX),
105
+ numAt(operands, MATRIX_E_INDEX),
106
+ numAt(operands, MATRIX_F_INDEX)
99
107
  ];
100
108
  }
101
109
  const SHAPE_ABS_TOLERANCE_PT = .001;
@@ -139,9 +147,10 @@ function closedPolygonCorners(subpath) {
139
147
  if (nearlyEqualPoints(first, last, shapeTolerance(Math.max(bounds.maxX - bounds.minX, bounds.maxY - bounds.minY)))) corners.pop();
140
148
  return corners;
141
149
  }
150
+ const RECTANGLE_CORNER_COUNT = 4;
142
151
  function detectRect(subpath, paint) {
143
152
  const corners = closedPolygonCorners(subpath);
144
- if (corners?.length !== 4) return;
153
+ if (corners?.length !== RECTANGLE_CORNER_COUNT) return;
145
154
  const { minX, minY, maxX, maxY } = boundsOf(corners);
146
155
  const widthPt = maxX - minX;
147
156
  const heightPt = maxY - minY;
@@ -189,9 +198,10 @@ function expectedEllipseControl(atExtreme, atExtremeKind, otherEnd, center, kx,
189
198
  y: atExtreme.y
190
199
  };
191
200
  }
201
+ const ELLIPSE_SEGMENT_COUNT = 4;
192
202
  function detectEllipse(subpath, paint) {
193
203
  const segments = subpath.segments;
194
- if (!subpath.closed || segments.length !== 4 || segments.some((segment) => segment.kind !== "cubic")) return;
204
+ if (!subpath.closed || segments.length !== ELLIPSE_SEGMENT_COUNT || segments.some((segment) => segment.kind !== "cubic")) return;
195
205
  const start = {
196
206
  x: subpath.startXPt,
197
207
  y: subpath.startYPt
@@ -217,16 +227,16 @@ function detectEllipse(subpath, paint) {
217
227
  y: finalSegment.yPt
218
228
  }, start, Math.max(tolX, tolY))) return;
219
229
  const extremes = onCurve.map((point) => cardinalExtremeOf(point, center, rx, ry, tolX, tolY));
220
- if (extremes.some((extreme) => extreme === void 0) || new Set(extremes).size !== 4) return;
230
+ if (extremes.some((extreme) => extreme === void 0) || new Set(extremes).size !== ELLIPSE_SEGMENT_COUNT) return;
221
231
  const kx = rx * BEZIER_KAPPA;
222
232
  const ky = ry * BEZIER_KAPPA;
223
233
  const controlTolerance = Math.max(tolX, tolY);
224
- for (let i = 0; i < 4; i += 1) {
234
+ for (let i = 0; i < ELLIPSE_SEGMENT_COUNT; i += 1) {
225
235
  const segment = segments[i];
226
236
  const from = onCurve[i];
227
237
  const fromKind = extremes[i];
228
- const to = onCurve[(i + 1) % 4];
229
- const toKind = extremes[(i + 1) % 4];
238
+ const to = onCurve[(i + 1) % ELLIPSE_SEGMENT_COUNT];
239
+ const toKind = extremes[(i + 1) % ELLIPSE_SEGMENT_COUNT];
230
240
  if (segment?.kind !== "cubic" || from === void 0 || to === void 0 || fromKind === void 0 || toKind === void 0) return;
231
241
  const expectedC1 = expectedEllipseControl(from, fromKind, to, center, kx, ky);
232
242
  const expectedC2 = expectedEllipseControl(to, toKind, from, center, kx, ky);
@@ -291,6 +301,11 @@ var MarkedContentStack = class {
291
301
  }
292
302
  }
293
303
  };
304
+ const RE_HEIGHT_INDEX = 3;
305
+ const OPERAND_INDEX_3 = 3;
306
+ const OPERAND_INDEX_4 = 4;
307
+ const OPERAND_INDEX_5 = 5;
308
+ const TZ_PERCENT_DIVISOR = 100;
294
309
  function interpretContentStream(bytes, resources, context) {
295
310
  return runContentStream(bytes, resources, {
296
311
  ctm: IDENTITY_MATRIX,
@@ -361,7 +376,7 @@ function runContentStream(bytes, resources, initialState, context, depth, marked
361
376
  const x = numAt(operands, 0);
362
377
  const y = numAt(operands, 1);
363
378
  const w = numAt(operands, 2);
364
- const h = numAt(operands, 3);
379
+ const h = numAt(operands, RE_HEIGHT_INDEX);
365
380
  const p1 = applyMatrix(ctm, {
366
381
  x,
367
382
  y
@@ -443,10 +458,10 @@ function runContentStream(bytes, resources, initialState, context, depth, marked
443
458
  });
444
459
  const widthPer1000 = glyph?.widthPer1000 ?? FALLBACK_GLYPH_WIDTH_PER_1000;
445
460
  const byteLength = glyph?.byteLengthConsumed ?? 1;
446
- const isSingleByteSpace = byteLength === 1 && codes[offset] === 32;
461
+ const isSingleByteSpace = byteLength === 1 && codes[offset] === ASCII_SPACE;
447
462
  const spacing = gs.charSpace + (isSingleByteSpace ? gs.wordSpace : 0);
448
463
  const vertical = glyph?.vertical;
449
- text.tm = vertical === void 0 ? multiplyMatrices(translationMatrix((widthPer1000 / 1e3 * gs.fontSizePt + spacing) * gs.horizScale, 0), text.tm) : multiplyMatrices(translationMatrix(0, vertical.displacementPer1000 / 1e3 * gs.fontSizePt + spacing), text.tm);
464
+ text.tm = vertical === void 0 ? multiplyMatrices(translationMatrix((widthPer1000 / GLYPH_SPACE_PER_TEXT_SPACE_UNIT * gs.fontSizePt + spacing) * gs.horizScale, 0), text.tm) : multiplyMatrices(translationMatrix(0, vertical.displacementPer1000 / GLYPH_SPACE_PER_TEXT_SPACE_UNIT * gs.fontSizePt + spacing), text.tm);
450
465
  offset += byteLength;
451
466
  }
452
467
  };
@@ -456,8 +471,8 @@ function runContentStream(bytes, resources, initialState, context, depth, marked
456
471
  const vertical = context.fontMetrics.glyphAdvance(fontResourceName, resources, codes, 0)?.vertical;
457
472
  if (vertical === void 0) return;
458
473
  return {
459
- x: vertical.positionXPer1000 / 1e3,
460
- y: vertical.positionYPer1000 / 1e3
474
+ x: vertical.positionXPer1000 / GLYPH_SPACE_PER_TEXT_SPACE_UNIT,
475
+ y: vertical.positionYPer1000 / GLYPH_SPACE_PER_TEXT_SPACE_UNIT
461
476
  };
462
477
  };
463
478
  const showTextArray = (elements) => {
@@ -474,7 +489,7 @@ function runContentStream(bytes, resources, initialState, context, depth, marked
474
489
  totalLength += el.bytes.length;
475
490
  advanceThroughString(el.bytes);
476
491
  } else if (el.kind === "number") {
477
- const adjustment = -(el.value / 1e3) * gs.fontSizePt;
492
+ const adjustment = -(el.value / GLYPH_SPACE_PER_TEXT_SPACE_UNIT) * gs.fontSizePt;
478
493
  text.tm = multiplyMatrices(vertical ? translationMatrix(0, adjustment) : translationMatrix(adjustment * gs.horizScale, 0), text.tm);
479
494
  }
480
495
  if (totalLength === 0) return;
@@ -672,11 +687,11 @@ function runContentStream(bytes, resources, initialState, context, depth, marked
672
687
  });
673
688
  const c2 = applyMatrix(gs.ctm, {
674
689
  x: numAt(operands, 2),
675
- y: numAt(operands, 3)
690
+ y: numAt(operands, OPERAND_INDEX_3)
676
691
  });
677
692
  const p = applyMatrix(gs.ctm, {
678
- x: numAt(operands, 4),
679
- y: numAt(operands, 5)
693
+ x: numAt(operands, OPERAND_INDEX_4),
694
+ y: numAt(operands, OPERAND_INDEX_5)
680
695
  });
681
696
  currentSubpath?.segments.push({
682
697
  kind: "cubic",
@@ -698,7 +713,7 @@ function runContentStream(bytes, resources, initialState, context, depth, marked
698
713
  });
699
714
  const p = applyMatrix(gs.ctm, {
700
715
  x: numAt(operands, 2),
701
- y: numAt(operands, 3)
716
+ y: numAt(operands, OPERAND_INDEX_3)
702
717
  });
703
718
  currentSubpath.segments.push({
704
719
  kind: "cubic",
@@ -718,7 +733,7 @@ function runContentStream(bytes, resources, initialState, context, depth, marked
718
733
  });
719
734
  const p = applyMatrix(gs.ctm, {
720
735
  x: numAt(operands, 2),
721
- y: numAt(operands, 3)
736
+ y: numAt(operands, OPERAND_INDEX_3)
722
737
  });
723
738
  currentSubpath?.segments.push({
724
739
  kind: "cubic",
@@ -783,7 +798,7 @@ function runContentStream(bytes, resources, initialState, context, depth, marked
783
798
  case "Tz":
784
799
  gs = {
785
800
  ...gs,
786
- horizScale: numAt(operands, 0) / 100
801
+ horizScale: numAt(operands, 0) / TZ_PERCENT_DIVISOR
787
802
  };
788
803
  break;
789
804
  case "TL":