pdf-parser.js 5.2.26 → 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 (221) 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.d.cts +2 -2
  7. package/dist/annotations.d.ts +2 -2
  8. package/dist/annotations.js +5 -3
  9. package/dist/attachments.d.cts +2 -2
  10. package/dist/attachments.d.ts +2 -2
  11. package/dist/builtin-encoding.cjs +17 -6
  12. package/dist/builtin-encoding.js +17 -6
  13. package/dist/bytes/crc32.cjs +5 -3
  14. package/dist/bytes/crc32.js +5 -3
  15. package/dist/bytes/flate.cjs +0 -1
  16. package/dist/bytes/flate.js +0 -1
  17. package/dist/cff-bounds.cjs +73 -45
  18. package/dist/cff-bounds.js +73 -45
  19. package/dist/cff.cjs +13 -6
  20. package/dist/cff.js +13 -6
  21. package/dist/cmap-table.cjs +54 -26
  22. package/dist/cmap-table.js +54 -26
  23. package/dist/cmap.cjs +5 -3
  24. package/dist/cmap.js +5 -3
  25. package/dist/content-read.d.cts +1 -1
  26. package/dist/content-read.d.ts +1 -1
  27. package/dist/content-write.cjs +21 -14
  28. package/dist/content-write.d.cts +2 -2
  29. package/dist/content-write.d.ts +2 -2
  30. package/dist/content-write.js +21 -14
  31. package/dist/crypto/aes.cjs +76 -55
  32. package/dist/crypto/aes.js +76 -55
  33. package/dist/crypto/md5.cjs +345 -149
  34. package/dist/crypto/md5.js +345 -149
  35. package/dist/crypto/rc4.cjs +5 -4
  36. package/dist/crypto/rc4.js +5 -4
  37. package/dist/crypto/sha2.cjs +92 -43
  38. package/dist/crypto/sha2.js +92 -43
  39. package/dist/document.cjs +17 -11
  40. package/dist/document.d.cts +1 -1
  41. package/dist/document.d.ts +1 -1
  42. package/dist/document.js +17 -11
  43. package/dist/{embedded-font-Bnhh4juV.d.ts → embedded-font-ByD7ZiQS.d.ts} +1 -1
  44. package/dist/{embedded-font-CEf-zBCA.d.cts → embedded-font-DgVBedw6.d.cts} +1 -1
  45. package/dist/embedded-font-write.d.cts +2 -2
  46. package/dist/embedded-font-write.d.ts +2 -2
  47. package/dist/embedded-font.cjs +4 -2
  48. package/dist/embedded-font.d.cts +1 -1
  49. package/dist/embedded-font.d.ts +1 -1
  50. package/dist/embedded-font.js +4 -2
  51. package/dist/encoding.cjs +1 -1
  52. package/dist/encoding.js +1 -1
  53. package/dist/encrypt-write.cjs +25 -21
  54. package/dist/encrypt-write.d.cts +1 -1
  55. package/dist/encrypt-write.d.ts +1 -1
  56. package/dist/encrypt-write.js +25 -21
  57. package/dist/encrypt.cjs +43 -64
  58. package/dist/encrypt.d.cts +1 -1
  59. package/dist/encrypt.d.ts +1 -1
  60. package/dist/encrypt.js +43 -64
  61. package/dist/filters.cjs +46 -26
  62. package/dist/filters.d.cts +1 -1
  63. package/dist/filters.d.ts +1 -1
  64. package/dist/filters.js +46 -26
  65. package/dist/font-face.cjs +2 -1
  66. package/dist/font-face.js +2 -1
  67. package/dist/font-read.cjs +12 -6
  68. package/dist/font-read.d.cts +1 -1
  69. package/dist/font-read.d.ts +1 -1
  70. package/dist/font-read.js +12 -6
  71. package/dist/font-registry.d.cts +3 -3
  72. package/dist/font-registry.d.ts +3 -3
  73. package/dist/font-tables.cjs +55 -28
  74. package/dist/font-tables.js +55 -28
  75. package/dist/form.cjs +13 -8
  76. package/dist/form.d.cts +2 -2
  77. package/dist/form.d.ts +2 -2
  78. package/dist/form.js +13 -8
  79. package/dist/gdef-table.cjs +6 -3
  80. package/dist/gdef-table.js +6 -3
  81. package/dist/{glyf-contours-C0epBNqP.d.ts → glyf-contours-B1PsI9oA.d.ts} +1 -1
  82. package/dist/{glyf-contours-BRpvd0rt.d.cts → glyf-contours-NHBpgks-.d.cts} +1 -1
  83. package/dist/glyf-contours.cjs +3 -1
  84. package/dist/glyf-contours.d.cts +1 -1
  85. package/dist/glyf-contours.d.ts +1 -1
  86. package/dist/glyf-contours.js +3 -1
  87. package/dist/glyf.cjs +22 -11
  88. package/dist/glyf.js +22 -11
  89. package/dist/gpos-table.cjs +37 -19
  90. package/dist/gpos-table.js +37 -19
  91. package/dist/gsub-table.cjs +40 -25
  92. package/dist/gsub-table.js +40 -25
  93. package/dist/hmtx-table.cjs +5 -3
  94. package/dist/hmtx-table.js +5 -3
  95. package/dist/image/ccitt-encode.cjs +8 -5
  96. package/dist/image/ccitt-encode.js +8 -5
  97. package/dist/image/ccitt.cjs +801 -209
  98. package/dist/image/ccitt.js +801 -209
  99. package/dist/image/jbig2-arith.cjs +340 -306
  100. package/dist/image/jbig2-arith.js +340 -306
  101. package/dist/image/jbig2-bitmap.cjs +8 -5
  102. package/dist/image/jbig2-bitmap.js +8 -5
  103. package/dist/image/jbig2-generic.cjs +240 -69
  104. package/dist/image/jbig2-generic.js +240 -69
  105. package/dist/image/jbig2-text.cjs +4 -2
  106. package/dist/image/jbig2-text.js +4 -2
  107. package/dist/image/jbig2.cjs +69 -31
  108. package/dist/image/jbig2.js +69 -31
  109. package/dist/image/jp2-boxes.cjs +52 -27
  110. package/dist/image/jp2-boxes.js +52 -27
  111. package/dist/image/jpeg-info.cjs +29 -24
  112. package/dist/image/jpeg-info.js +29 -24
  113. package/dist/image/jpeg2000-codestream.cjs +61 -32
  114. package/dist/image/jpeg2000-codestream.js +61 -32
  115. package/dist/image/jpeg2000-dwt.cjs +2 -1
  116. package/dist/image/jpeg2000-dwt.js +2 -1
  117. package/dist/image/jpeg2000-t1.cjs +21 -11
  118. package/dist/image/jpeg2000-t1.js +21 -11
  119. package/dist/image/jpeg2000-t2.cjs +12 -5
  120. package/dist/image/jpeg2000-t2.js +12 -5
  121. package/dist/image/jpeg2000-tagtree.cjs +8 -4
  122. package/dist/image/jpeg2000-tagtree.js +8 -4
  123. package/dist/image/jpeg2000.cjs +11 -6
  124. package/dist/image/jpeg2000.js +11 -6
  125. package/dist/image/png-decode.cjs +62 -39
  126. package/dist/image/png-decode.d.cts +3 -2
  127. package/dist/image/png-decode.d.ts +3 -2
  128. package/dist/image/png-decode.js +62 -39
  129. package/dist/image/png-filter.cjs +23 -15
  130. package/dist/image/png-filter.js +23 -15
  131. package/dist/images-read.cjs +41 -36
  132. package/dist/images-read.d.cts +2 -2
  133. package/dist/images-read.d.ts +2 -2
  134. package/dist/images-read.js +41 -36
  135. package/dist/index.cjs +1 -1
  136. package/dist/index.d.cts +1 -1
  137. package/dist/index.d.ts +1 -1
  138. package/dist/index.js +1 -1
  139. package/dist/interpret.cjs +68 -40
  140. package/dist/interpret.d.cts +1 -1
  141. package/dist/interpret.d.ts +1 -1
  142. package/dist/interpret.js +68 -40
  143. package/dist/lexer.cjs +86 -51
  144. package/dist/lexer.js +86 -51
  145. package/dist/math-content-write.cjs +9 -5
  146. package/dist/math-content-write.js +9 -5
  147. package/dist/math-font-write.cjs +2 -1
  148. package/dist/math-font-write.d.cts +1 -1
  149. package/dist/math-font-write.d.ts +1 -1
  150. package/dist/math-font-write.js +2 -1
  151. package/dist/math-font.cjs +16 -7
  152. package/dist/math-font.js +16 -7
  153. package/dist/math-table.cjs +25 -13
  154. package/dist/math-table.js +25 -13
  155. package/dist/matrix.cjs +3 -2
  156. package/dist/matrix.js +3 -2
  157. package/dist/measure.cjs +1 -1
  158. package/dist/measure.js +1 -1
  159. package/dist/names.cjs +7 -7
  160. package/dist/names.d.cts +2 -2
  161. package/dist/names.d.ts +2 -2
  162. package/dist/names.js +7 -7
  163. package/dist/navigation.cjs +16 -12
  164. package/dist/navigation.d.cts +4 -4
  165. package/dist/navigation.d.ts +4 -4
  166. package/dist/navigation.js +16 -12
  167. package/dist/{objects-B7HdMeWS.d.cts → objects-e2RS3-yT.d.cts} +3 -3
  168. package/dist/{objects-B7HdMeWS.d.ts → objects-e2RS3-yT.d.ts} +3 -3
  169. package/dist/objects.d.cts +1 -1
  170. package/dist/objects.d.ts +1 -1
  171. package/dist/optional-content.d.cts +2 -2
  172. package/dist/optional-content.d.ts +2 -2
  173. package/dist/ot-layout-common.cjs +22 -15
  174. package/dist/ot-layout-common.js +22 -15
  175. package/dist/parse.cjs +7 -5
  176. package/dist/parse.d.cts +1 -1
  177. package/dist/parse.d.ts +1 -1
  178. package/dist/parse.js +7 -5
  179. package/dist/pdf-text.cjs +5 -2
  180. package/dist/pdf-text.js +5 -2
  181. package/dist/predictors.cjs +14 -9
  182. package/dist/predictors.d.cts +1 -1
  183. package/dist/predictors.d.ts +1 -1
  184. package/dist/predictors.js +14 -9
  185. package/dist/raster.cjs +30 -19
  186. package/dist/raster.d.cts +8 -8
  187. package/dist/raster.d.ts +8 -8
  188. package/dist/raster.js +30 -19
  189. package/dist/read.cjs +29 -16
  190. package/dist/read.js +29 -16
  191. package/dist/serialize.cjs +6 -2
  192. package/dist/serialize.d.cts +1 -1
  193. package/dist/serialize.d.ts +1 -1
  194. package/dist/serialize.js +6 -2
  195. package/dist/sfnt-subset.cjs +25 -13
  196. package/dist/sfnt-subset.d.cts +1 -1
  197. package/dist/sfnt-subset.d.ts +1 -1
  198. package/dist/sfnt-subset.js +25 -13
  199. package/dist/sfnt.cjs +20 -10
  200. package/dist/sfnt.js +20 -10
  201. package/dist/structure.d.cts +2 -2
  202. package/dist/structure.d.ts +2 -2
  203. package/dist/text-group.cjs +0 -1
  204. package/dist/text-group.js +0 -1
  205. package/dist/text-layout.d.cts +1 -1
  206. package/dist/text-layout.d.ts +1 -1
  207. package/dist/tounicode.cjs +4 -2
  208. package/dist/tounicode.d.cts +1 -1
  209. package/dist/tounicode.d.ts +1 -1
  210. package/dist/tounicode.js +4 -2
  211. package/dist/winansi.cjs +1 -1
  212. package/dist/winansi.js +1 -1
  213. package/dist/write.cjs +20 -12
  214. package/dist/write.d.cts +1 -1
  215. package/dist/write.d.ts +1 -1
  216. package/dist/write.js +20 -12
  217. package/dist/xref.cjs +5 -2
  218. package/dist/xref.d.cts +1 -1
  219. package/dist/xref.d.ts +1 -1
  220. package/dist/xref.js +5 -2
  221. package/package.json +1 -1
package/dist/parse.d.cts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { PdfDiagnosticSink } from "./diagnostics.cjs";
2
- import { r as PdfObject } from "./objects-B7HdMeWS.cjs";
2
+ import { r as PdfObject } from "./objects-e2RS3-yT.cjs";
3
3
  import { ByteReader } from "./bytes/reader.cjs";
4
4
  //#region src/parse.d.ts
5
5
  declare function parseValue(reader: ByteReader, sink: PdfDiagnosticSink): PdfObject | undefined;
package/dist/parse.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { PdfDiagnosticSink } from "./diagnostics.js";
2
- import { r as PdfObject } from "./objects-B7HdMeWS.js";
2
+ import { r as PdfObject } from "./objects-e2RS3-yT.js";
3
3
  import { ByteReader } from "./bytes/reader.js";
4
4
  //#region src/parse.d.ts
5
5
  declare function parseValue(reader: ByteReader, sink: PdfDiagnosticSink): PdfObject | undefined;
package/dist/parse.js CHANGED
@@ -109,10 +109,12 @@ function parseDictOrStreamBody(reader, sink) {
109
109
  reader.reset(afterDictMark);
110
110
  return dict;
111
111
  }
112
+ const CARRIAGE_RETURN = 13;
113
+ const LINE_FEED = 10;
112
114
  function skipStreamDataStart(reader, sink) {
113
- if (reader.peek() === 13) {
115
+ if (reader.peek() === CARRIAGE_RETURN) {
114
116
  reader.next();
115
- if (reader.peek() === 10) reader.next();
117
+ if (reader.peek() === LINE_FEED) reader.next();
116
118
  else sink({
117
119
  code: "pdf/stream-bad-eol",
118
120
  severity: "warning",
@@ -120,7 +122,7 @@ function skipStreamDataStart(reader, sink) {
120
122
  });
121
123
  return;
122
124
  }
123
- if (reader.peek() === 10) {
125
+ if (reader.peek() === LINE_FEED) {
124
126
  reader.next();
125
127
  return;
126
128
  }
@@ -186,8 +188,8 @@ function findEndstreamOffset(reader, fromOffset) {
186
188
  }
187
189
  function trimTrailingStreamEol(reader, dataStart, endstreamOffset) {
188
190
  const precedingTwo = reader.slice(Math.max(dataStart, endstreamOffset - 2), endstreamOffset);
189
- if (precedingTwo.length >= 2 && precedingTwo[precedingTwo.length - 2] === 13 && precedingTwo[precedingTwo.length - 1] === 10) return endstreamOffset - 2;
190
- if (precedingTwo.length >= 1 && (precedingTwo[precedingTwo.length - 1] === 10 || precedingTwo[precedingTwo.length - 1] === 13)) return endstreamOffset - 1;
191
+ if (precedingTwo.length >= 2 && precedingTwo[precedingTwo.length - 2] === CARRIAGE_RETURN && precedingTwo[precedingTwo.length - 1] === LINE_FEED) return endstreamOffset - 2;
192
+ if (precedingTwo.length >= 1 && (precedingTwo[precedingTwo.length - 1] === LINE_FEED || precedingTwo[precedingTwo.length - 1] === CARRIAGE_RETURN)) return endstreamOffset - 1;
191
193
  return endstreamOffset;
192
194
  }
193
195
  function parseIndirectObject(reader, sink) {
package/dist/pdf-text.cjs CHANGED
@@ -1,9 +1,12 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
2
  //#region src/pdf-text.ts
3
+ const UTF16BE_BOM_BYTE_0 = 254;
4
+ const UTF16BE_BOM_BYTE_1 = 255;
5
+ const BITS_PER_BYTE = 8;
3
6
  function decodePdfString(bytes) {
4
- if (bytes.length >= 2 && bytes[0] === 254 && bytes[1] === 255) {
7
+ if (bytes.length >= 2 && bytes[0] === UTF16BE_BOM_BYTE_0 && bytes[1] === UTF16BE_BOM_BYTE_1) {
5
8
  let out = "";
6
- for (let i = 2; i + 1 < bytes.length; i += 2) out += String.fromCharCode((bytes[i] ?? 0) << 8 | (bytes[i + 1] ?? 0));
9
+ for (let i = 2; i + 1 < bytes.length; i += 2) out += String.fromCharCode((bytes[i] ?? 0) << BITS_PER_BYTE | (bytes[i + 1] ?? 0));
7
10
  return out;
8
11
  }
9
12
  return Array.from(bytes, (b) => String.fromCharCode(b)).join("");
package/dist/pdf-text.js CHANGED
@@ -1,8 +1,11 @@
1
1
  //#region src/pdf-text.ts
2
+ const UTF16BE_BOM_BYTE_0 = 254;
3
+ const UTF16BE_BOM_BYTE_1 = 255;
4
+ const BITS_PER_BYTE = 8;
2
5
  function decodePdfString(bytes) {
3
- if (bytes.length >= 2 && bytes[0] === 254 && bytes[1] === 255) {
6
+ if (bytes.length >= 2 && bytes[0] === UTF16BE_BOM_BYTE_0 && bytes[1] === UTF16BE_BOM_BYTE_1) {
4
7
  let out = "";
5
- for (let i = 2; i + 1 < bytes.length; i += 2) out += String.fromCharCode((bytes[i] ?? 0) << 8 | (bytes[i + 1] ?? 0));
8
+ for (let i = 2; i + 1 < bytes.length; i += 2) out += String.fromCharCode((bytes[i] ?? 0) << BITS_PER_BYTE | (bytes[i + 1] ?? 0));
6
9
  return out;
7
10
  }
8
11
  return Array.from(bytes, (b) => String.fromCharCode(b)).join("");
@@ -6,6 +6,11 @@ const DEFAULT_PREDICTOR = 1;
6
6
  const DEFAULT_COLORS = 1;
7
7
  const DEFAULT_BITS_PER_COMPONENT = 8;
8
8
  const DEFAULT_COLUMNS = 1;
9
+ const BITS_PER_BYTE = 8;
10
+ const BYTE_MASK = 255;
11
+ const PNG_PREDICTOR_CODE_MIN = 10;
12
+ const SIXTEEN_BIT_COMPONENT = 16;
13
+ const SIXTEEN_BIT_SAMPLE_MASK = 65535;
9
14
  function readPredictorParams(parms) {
10
15
  return {
11
16
  predictor: require_objects.asNumber(parms ? require_objects.dictGet(parms, "Predictor") : void 0) ?? DEFAULT_PREDICTOR,
@@ -16,10 +21,10 @@ function readPredictorParams(parms) {
16
21
  }
17
22
  function applyPredictor(data, params, sink) {
18
23
  if (params.predictor <= 1) return data;
19
- const bpp = Math.max(1, Math.ceil(params.colors * params.bitsPerComponent / 8));
20
- const bytesPerRow = Math.ceil(params.colors * params.bitsPerComponent * params.columns / 8);
24
+ const bpp = Math.max(1, Math.ceil(params.colors * params.bitsPerComponent / BITS_PER_BYTE));
25
+ const bytesPerRow = Math.ceil(params.colors * params.bitsPerComponent * params.columns / BITS_PER_BYTE);
21
26
  if (params.predictor === 2) return applyTiffPredictor(data, params, bytesPerRow, sink);
22
- if (params.predictor >= 10) {
27
+ if (params.predictor >= PNG_PREDICTOR_CODE_MIN) {
23
28
  const height = bytesPerRow > 0 ? Math.floor(data.length / (bytesPerRow + 1)) : 0;
24
29
  return require_image_png_filter.unfilterScanlines(data, height, bytesPerRow, bpp);
25
30
  }
@@ -31,7 +36,7 @@ function applyPredictor(data, params, sink) {
31
36
  return data;
32
37
  }
33
38
  function applyTiffPredictor(data, params, bytesPerRow, sink) {
34
- if (params.bitsPerComponent !== 8 && params.bitsPerComponent !== 16) {
39
+ if (params.bitsPerComponent !== BITS_PER_BYTE && params.bitsPerComponent !== SIXTEEN_BIT_COMPONENT) {
35
40
  sink({
36
41
  code: "pdf/unsupported-predictor",
37
42
  severity: "warning",
@@ -42,18 +47,18 @@ function applyTiffPredictor(data, params, bytesPerRow, sink) {
42
47
  const out = new Uint8Array(data.length);
43
48
  out.set(data);
44
49
  const rowCount = bytesPerRow > 0 ? Math.floor(out.length / bytesPerRow) : 0;
45
- const componentStride = params.bitsPerComponent === 16 ? 2 : 1;
50
+ const componentStride = params.bitsPerComponent === SIXTEEN_BIT_COMPONENT ? 2 : 1;
46
51
  const componentsPerPixel = params.colors;
47
52
  for (let row = 0; row < rowCount; row++) {
48
53
  const rowStart = row * bytesPerRow;
49
54
  for (let component = componentsPerPixel; component * componentStride < bytesPerRow; component++) {
50
55
  const i = rowStart + component * componentStride;
51
56
  const prevI = i - componentsPerPixel * componentStride;
52
- if (componentStride === 1) out[i] = (out[i] ?? 0) + (out[prevI] ?? 0) & 255;
57
+ if (componentStride === 1) out[i] = (out[i] ?? 0) + (out[prevI] ?? 0) & BYTE_MASK;
53
58
  else {
54
- const sum = ((out[i] ?? 0) << 8 | (out[i + 1] ?? 0)) + ((out[prevI] ?? 0) << 8 | (out[prevI + 1] ?? 0)) & 65535;
55
- out[i] = sum >> 8 & 255;
56
- out[i + 1] = sum & 255;
59
+ const sum = ((out[i] ?? 0) << BITS_PER_BYTE | (out[i + 1] ?? 0)) + ((out[prevI] ?? 0) << BITS_PER_BYTE | (out[prevI + 1] ?? 0)) & SIXTEEN_BIT_SAMPLE_MASK;
60
+ out[i] = sum >> BITS_PER_BYTE & BYTE_MASK;
61
+ out[i + 1] = sum & BYTE_MASK;
57
62
  }
58
63
  }
59
64
  }
@@ -1,5 +1,5 @@
1
1
  import { PdfDiagnosticSink } from "./diagnostics.cjs";
2
- import { n as PdfDict } from "./objects-B7HdMeWS.cjs";
2
+ import { n as PdfDict } from "./objects-e2RS3-yT.cjs";
3
3
  //#region src/predictors.d.ts
4
4
  interface PredictorParams {
5
5
  readonly predictor: number;
@@ -1,5 +1,5 @@
1
1
  import { PdfDiagnosticSink } from "./diagnostics.js";
2
- import { n as PdfDict } from "./objects-B7HdMeWS.js";
2
+ import { n as PdfDict } from "./objects-e2RS3-yT.js";
3
3
  //#region src/predictors.d.ts
4
4
  interface PredictorParams {
5
5
  readonly predictor: number;
@@ -5,6 +5,11 @@ const DEFAULT_PREDICTOR = 1;
5
5
  const DEFAULT_COLORS = 1;
6
6
  const DEFAULT_BITS_PER_COMPONENT = 8;
7
7
  const DEFAULT_COLUMNS = 1;
8
+ const BITS_PER_BYTE = 8;
9
+ const BYTE_MASK = 255;
10
+ const PNG_PREDICTOR_CODE_MIN = 10;
11
+ const SIXTEEN_BIT_COMPONENT = 16;
12
+ const SIXTEEN_BIT_SAMPLE_MASK = 65535;
8
13
  function readPredictorParams(parms) {
9
14
  return {
10
15
  predictor: asNumber(parms ? dictGet(parms, "Predictor") : void 0) ?? DEFAULT_PREDICTOR,
@@ -15,10 +20,10 @@ function readPredictorParams(parms) {
15
20
  }
16
21
  function applyPredictor(data, params, sink) {
17
22
  if (params.predictor <= 1) return data;
18
- const bpp = Math.max(1, Math.ceil(params.colors * params.bitsPerComponent / 8));
19
- const bytesPerRow = Math.ceil(params.colors * params.bitsPerComponent * params.columns / 8);
23
+ const bpp = Math.max(1, Math.ceil(params.colors * params.bitsPerComponent / BITS_PER_BYTE));
24
+ const bytesPerRow = Math.ceil(params.colors * params.bitsPerComponent * params.columns / BITS_PER_BYTE);
20
25
  if (params.predictor === 2) return applyTiffPredictor(data, params, bytesPerRow, sink);
21
- if (params.predictor >= 10) {
26
+ if (params.predictor >= PNG_PREDICTOR_CODE_MIN) {
22
27
  const height = bytesPerRow > 0 ? Math.floor(data.length / (bytesPerRow + 1)) : 0;
23
28
  return unfilterScanlines(data, height, bytesPerRow, bpp);
24
29
  }
@@ -30,7 +35,7 @@ function applyPredictor(data, params, sink) {
30
35
  return data;
31
36
  }
32
37
  function applyTiffPredictor(data, params, bytesPerRow, sink) {
33
- if (params.bitsPerComponent !== 8 && params.bitsPerComponent !== 16) {
38
+ if (params.bitsPerComponent !== BITS_PER_BYTE && params.bitsPerComponent !== SIXTEEN_BIT_COMPONENT) {
34
39
  sink({
35
40
  code: "pdf/unsupported-predictor",
36
41
  severity: "warning",
@@ -41,18 +46,18 @@ function applyTiffPredictor(data, params, bytesPerRow, sink) {
41
46
  const out = new Uint8Array(data.length);
42
47
  out.set(data);
43
48
  const rowCount = bytesPerRow > 0 ? Math.floor(out.length / bytesPerRow) : 0;
44
- const componentStride = params.bitsPerComponent === 16 ? 2 : 1;
49
+ const componentStride = params.bitsPerComponent === SIXTEEN_BIT_COMPONENT ? 2 : 1;
45
50
  const componentsPerPixel = params.colors;
46
51
  for (let row = 0; row < rowCount; row++) {
47
52
  const rowStart = row * bytesPerRow;
48
53
  for (let component = componentsPerPixel; component * componentStride < bytesPerRow; component++) {
49
54
  const i = rowStart + component * componentStride;
50
55
  const prevI = i - componentsPerPixel * componentStride;
51
- if (componentStride === 1) out[i] = (out[i] ?? 0) + (out[prevI] ?? 0) & 255;
56
+ if (componentStride === 1) out[i] = (out[i] ?? 0) + (out[prevI] ?? 0) & BYTE_MASK;
52
57
  else {
53
- const sum = ((out[i] ?? 0) << 8 | (out[i + 1] ?? 0)) + ((out[prevI] ?? 0) << 8 | (out[prevI + 1] ?? 0)) & 65535;
54
- out[i] = sum >> 8 & 255;
55
- out[i + 1] = sum & 255;
58
+ const sum = ((out[i] ?? 0) << BITS_PER_BYTE | (out[i + 1] ?? 0)) + ((out[prevI] ?? 0) << BITS_PER_BYTE | (out[prevI + 1] ?? 0)) & SIXTEEN_BIT_SAMPLE_MASK;
59
+ out[i] = sum >> BITS_PER_BYTE & BYTE_MASK;
60
+ out[i + 1] = sum & BYTE_MASK;
56
61
  }
57
62
  }
58
63
  }
package/dist/raster.cjs CHANGED
@@ -17,13 +17,16 @@ const require_read = require("./read.cjs");
17
17
  const require_glyf = require("./glyf.cjs");
18
18
  const require_glyf_contours = require("./glyf-contours.cjs");
19
19
  //#region src/raster.ts
20
+ const PIXEL_ROUNDING_EPSILON = 1e-9;
21
+ const POINTS_PER_INCH = 72;
22
+ const EXTENT_ZERO_EPSILON = 1e-9;
20
23
  function regionPixels(extentPt, scale) {
21
- return Math.max(1, Math.ceil(extentPt * scale - 1e-9));
24
+ return Math.max(1, Math.ceil(extentPt * scale - PIXEL_ROUNDING_EPSILON));
22
25
  }
23
26
  function renderPdfPage(pdfBytes, pageIndex, options, rasteriser) {
24
27
  const sink = options.sink ?? require_diagnostics.NOOP_DIAGNOSTIC_SINK;
25
28
  if (options.scale !== void 0 && options.dpi !== void 0) throw new Error("renderPdfPage accepts at most one of scale and dpi; they name the same factor in different units (dpi = 72 x scale)");
26
- const scale = options.dpi !== void 0 ? options.dpi / 72 : options.scale;
29
+ const scale = options.dpi !== void 0 ? options.dpi / POINTS_PER_INCH : options.scale;
27
30
  if (scale !== void 0 && !(scale > 0)) throw new Error(`renderPdfPage requires a positive scale factor (received scale ${options.scale}, dpi ${options.dpi})`);
28
31
  const pixelsPerPt = scale ?? 1;
29
32
  if (options.clipPt !== void 0 && (!(options.clipPt.widthPt > 0) || !(options.clipPt.heightPt > 0))) throw new Error("renderPdfPage clipPt must carry positive widthPt and heightPt; a zero-extent region has no pixels to render");
@@ -195,6 +198,7 @@ function drawRect(item, matrix, pixelsPerPt, rasteriser) {
195
198
  stroke: strokeSpec(item.stroke, void 0, pixelsPerPt)
196
199
  });
197
200
  }
201
+ const ELLIPSE_QUADRANT_COUNT = 4;
198
202
  function drawEllipse(item, matrix, pixelsPerPt, rasteriser) {
199
203
  const cx = item.xPt + item.widthPt / 2;
200
204
  const cy = item.yPt + item.heightPt / 2;
@@ -224,8 +228,8 @@ function drawEllipse(item, matrix, pixelsPerPt, rasteriser) {
224
228
  });
225
229
  const start = transformed(cardinalPoints[0]);
226
230
  const segments = [];
227
- for (let i = 0; i < 4; i++) {
228
- const end = transformed(cardinalPoints[(i + 1) % 4]);
231
+ for (let i = 0; i < ELLIPSE_QUADRANT_COUNT; i++) {
232
+ const end = transformed(cardinalPoints[(i + 1) % ELLIPSE_QUADRANT_COUNT]);
229
233
  const c1 = transformed(controls[i * 2]);
230
234
  const c2 = transformed(controls[i * 2 + 1]);
231
235
  segments.push({
@@ -402,12 +406,13 @@ function drawImage(image, ctm, interpretToDeviceMatrix, rasteriser) {
402
406
  matrix
403
407
  });
404
408
  }
409
+ const DASHED_STROKE_WIDTH_MULTIPLE = 3;
405
410
  function strokeSpec(stroke, style, pixelsPerPt) {
406
411
  const widthPx = stroke.widthPt * pixelsPerPt;
407
412
  if (style === "dashed") return {
408
413
  color: stroke.color,
409
414
  widthPx,
410
- dashPx: [widthPx * 3, widthPx * 3]
415
+ dashPx: [widthPx * DASHED_STROKE_WIDTH_MULTIPLE, widthPx * DASHED_STROKE_WIDTH_MULTIPLE]
411
416
  };
412
417
  return {
413
418
  color: stroke.color,
@@ -475,6 +480,7 @@ function flattenCubic(p0, c1, c2, p1) {
475
480
  flatten(p0, c1, c2, p1, 0);
476
481
  return points;
477
482
  }
483
+ const CFF_HEADER_SIZE = 4;
478
484
  function openEmbeddedProgram(descriptorOwner, resolver) {
479
485
  const descriptor = resolver.resolveDict(require_objects.dictGet(descriptorOwner, "FontDescriptor"));
480
486
  if (descriptor === void 0) return { kind: "absent" };
@@ -482,7 +488,7 @@ function openEmbeddedProgram(descriptorOwner, resolver) {
482
488
  const stream = resolver.resolve(require_objects.dictGet(descriptor, key));
483
489
  if (stream?.kind !== "stream") continue;
484
490
  const bytes = require_filters.decodeStream(stream.raw, stream.dict, require_diagnostics.NOOP_DIAGNOSTIC_SINK).bytes;
485
- if (bytes[0] === 1 && bytes[1] === 0 && bytes[2] === 4) return { kind: "cff" };
491
+ if (bytes[0] === 1 && bytes[1] === 0 && bytes[2] === CFF_HEADER_SIZE) return { kind: "cff" };
486
492
  const sfnt = require_sfnt.parseSfnt(bytes);
487
493
  if (sfnt === void 0) continue;
488
494
  if (sfnt.tables.has("CFF ")) return { kind: "cff" };
@@ -514,6 +520,7 @@ function resolveTextOutlineFace(fontResourceName, resources, resolver, fontResol
514
520
  outlineFaces.set(fontDict, face);
515
521
  return face;
516
522
  }
523
+ const BITS_PER_BYTE = 8;
517
524
  function buildTextOutlineFace(fontDict, resolver, fontResolver, fontResourceName, resources, sink) {
518
525
  const faceName = require_objects.asName(require_objects.dictGet(fontDict, "BaseFont")) ?? require_objects.asName(require_objects.dictGet(fontDict, "Subtype")) ?? "font";
519
526
  const unavailable = (reason) => {
@@ -548,12 +555,12 @@ function buildTextOutlineFace(fontDict, resolver, fontResolver, fontResourceName
548
555
  if (cidToGidMap?.kind === "stream") {
549
556
  const decodedBytes = require_filters.decodeStream(cidToGidMap.raw, cidToGidMap.dict, require_diagnostics.NOOP_DIAGNOSTIC_SINK).bytes;
550
557
  const entries = [];
551
- for (let i = 0; i + 1 < decodedBytes.length; i += 2) entries.push(decodedBytes[i] << 8 | decodedBytes[i + 1]);
558
+ for (let i = 0; i + 1 < decodedBytes.length; i += 2) entries.push(decodedBytes[i] << BITS_PER_BYTE | decodedBytes[i + 1]);
552
559
  return {
553
560
  glyf: program.face.glyf,
554
561
  unitsPerEm: program.face.unitsPerEm,
555
562
  glyphIdOf: (codes, offset) => {
556
- const cid = codes[offset] << 8 | codes[offset + 1];
563
+ const cid = codes[offset] << BITS_PER_BYTE | codes[offset + 1];
557
564
  return entries[cid];
558
565
  }
559
566
  };
@@ -561,7 +568,7 @@ function buildTextOutlineFace(fontDict, resolver, fontResolver, fontResourceName
561
568
  return {
562
569
  glyf: program.face.glyf,
563
570
  unitsPerEm: program.face.unitsPerEm,
564
- glyphIdOf: (codes, offset) => codes[offset] << 8 | codes[offset + 1]
571
+ glyphIdOf: (codes, offset) => codes[offset] << BITS_PER_BYTE | codes[offset + 1]
565
572
  };
566
573
  }
567
574
  if (subtype === "TrueType") {
@@ -585,6 +592,7 @@ function buildTextOutlineFace(fontDict, resolver, fontResolver, fontResourceName
585
592
  }
586
593
  return unavailable(`a font of subtype ${subtype ?? "(none)"} (a Type3 glyph-procedure font has no static outline at all)`);
587
594
  }
595
+ const METRICS_PER_1000_SCALE = 1e3;
588
596
  function drawTextRun(item, fontResolver, resolver, outlineFaces, interpretToDeviceMatrix, rasteriser, sink) {
589
597
  const face = resolveTextOutlineFace(item.fontResourceName, item.resources, resolver, fontResolver, outlineFaces, sink);
590
598
  if (face === void 0) return;
@@ -597,10 +605,10 @@ function drawTextRun(item, fontResolver, resolver, outlineFaces, interpretToDevi
597
605
  placements.push({
598
606
  glyphId: face.glyphIdOf(item.codes, offset),
599
607
  advance: cumulative,
600
- positionX: (advance.vertical?.positionXPer1000 ?? 0) / 1e3,
601
- positionY: (advance.vertical?.positionYPer1000 ?? 0) / 1e3
608
+ positionX: (advance.vertical?.positionXPer1000 ?? 0) / METRICS_PER_1000_SCALE,
609
+ positionY: (advance.vertical?.positionYPer1000 ?? 0) / METRICS_PER_1000_SCALE
602
610
  });
603
- cumulative += (advance.vertical?.displacementPer1000 ?? advance.widthPer1000) / 1e3 * item.sizePt;
611
+ cumulative += (advance.vertical?.displacementPer1000 ?? advance.widthPer1000) / METRICS_PER_1000_SCALE * item.sizePt;
604
612
  offset += byteLength;
605
613
  }
606
614
  const startDeviceMatrix = require_matrix.multiplyMatrices(item.startMatrix, interpretToDeviceMatrix);
@@ -623,7 +631,7 @@ function drawTextRun(item, fontResolver, resolver, outlineFaces, interpretToDevi
623
631
  });
624
632
  const rawExtent = Math.hypot(rawEndPoint.x - startPoint.x, rawEndPoint.y - startPoint.y);
625
633
  const actualExtent = Math.hypot(endPoint.x - startPoint.x, endPoint.y - startPoint.y);
626
- const correction = rawExtent > 1e-9 ? actualExtent / rawExtent : 1;
634
+ const correction = rawExtent > EXTENT_ZERO_EPSILON ? actualExtent / rawExtent : 1;
627
635
  const firstPlacement = placements[0];
628
636
  const glyphScale = require_matrix.scaleMatrix(1 / face.unitsPerEm, 1 / face.unitsPerEm);
629
637
  for (const placement of placements) {
@@ -646,10 +654,12 @@ function drawGlyphOutline(outline, glyphMatrix, color, rasteriser) {
646
654
  }
647
655
  });
648
656
  }
657
+ const MIN_CONTOUR_POINTS = 3;
658
+ const QUADRATIC_TO_CUBIC_CONTROL_FRACTION = 2 / 3;
649
659
  function glyphOutlineSubpaths(outline, matrix) {
650
660
  const subpaths = [];
651
661
  for (const contour of outline.contours) {
652
- if (contour.length < 3) continue;
662
+ if (contour.length < MIN_CONTOUR_POINTS) continue;
653
663
  const firstOn = contour.findIndex((point) => point.onCurve);
654
664
  const contourPoints = contour.map((point) => ({
655
665
  x: point.x,
@@ -674,10 +684,10 @@ function glyphOutlineSubpaths(outline, matrix) {
674
684
  const p1 = require_matrix.applyMatrix(matrix, to);
675
685
  segments.push({
676
686
  kind: "cubic",
677
- c1xPx: p0.x + 2 / 3 * (q.x - p0.x),
678
- c1yPx: p0.y + 2 / 3 * (q.y - p0.y),
679
- c2xPx: p1.x + 2 / 3 * (q.x - p1.x),
680
- c2yPx: p1.y + 2 / 3 * (q.y - p1.y),
687
+ c1xPx: p0.x + QUADRATIC_TO_CUBIC_CONTROL_FRACTION * (q.x - p0.x),
688
+ c1yPx: p0.y + QUADRATIC_TO_CUBIC_CONTROL_FRACTION * (q.y - p0.y),
689
+ c2xPx: p1.x + QUADRATIC_TO_CUBIC_CONTROL_FRACTION * (q.x - p1.x),
690
+ c2yPx: p1.y + QUADRATIC_TO_CUBIC_CONTROL_FRACTION * (q.y - p1.y),
681
691
  xPx: p1.x,
682
692
  yPx: p1.y
683
693
  });
@@ -765,6 +775,7 @@ function rotatedRectBounds(rect, matrix) {
765
775
  maxY: Math.max(...ys)
766
776
  };
767
777
  }
778
+ const NEWLINE_BYTE = 10;
768
779
  function readPageContentBytes(page, resolver, sink) {
769
780
  const contentsObj = resolver.resolve(require_objects.dictGet(page, "Contents"));
770
781
  if (contentsObj?.kind === "stream") return require_filters.decodeStream(contentsObj.raw, contentsObj.dict, sink).bytes;
@@ -772,7 +783,7 @@ function readPageContentBytes(page, resolver, sink) {
772
783
  const chunks = [];
773
784
  for (const entry of contentsObj.items) {
774
785
  const streamObj = resolver.resolve(entry);
775
- if (streamObj?.kind === "stream") chunks.push(require_filters.decodeStream(streamObj.raw, streamObj.dict, sink).bytes, new Uint8Array([10]));
786
+ if (streamObj?.kind === "stream") chunks.push(require_filters.decodeStream(streamObj.raw, streamObj.dict, sink).bytes, new Uint8Array([NEWLINE_BYTE]));
776
787
  }
777
788
  return require_bytes_writer.concatBytes(chunks);
778
789
  }
package/dist/raster.d.cts CHANGED
@@ -1,6 +1,6 @@
1
1
  import { PdfDiagnosticSink } from "./diagnostics.cjs";
2
2
  import { r as Matrix } from "./matrix-B7_SBKQ5.cjs";
3
- import { n as GlyphOutline } from "./glyf-contours-BRpvd0rt.cjs";
3
+ import { n as GlyphOutline } from "./glyf-contours-NHBpgks-.cjs";
4
4
  import { Color } from "document-schema.js";
5
5
  //#region src/raster.d.ts
6
6
  type RasterMatrix = readonly [number, number, number, number, number, number];
@@ -80,24 +80,24 @@ interface RenderPdfPageOptions {
80
80
  readonly sink?: PdfDiagnosticSink;
81
81
  readonly signal?: AbortSignal;
82
82
  }
83
- declare function renderPdfPage(pdfBytes: Uint8Array<ArrayBuffer>, pageIndex: number, options: RenderPdfPageOptions, rasteriser: PageRasteriser): Uint8Array<ArrayBuffer> | Promise<Uint8Array<ArrayBuffer>>;
84
- declare function flattenCubic(p0: {
83
+ declare function renderPdfPage(pdfBytes: Uint8Array<ArrayBuffer>, pageIndex: number, options: RenderPdfPageOptions, rasteriser: Readonly<PageRasteriser>): Uint8Array<ArrayBuffer> | Promise<Uint8Array<ArrayBuffer>>;
84
+ declare function flattenCubic(p0: Readonly<{
85
85
  x: number;
86
86
  y: number;
87
- }, c1: {
87
+ }>, c1: Readonly<{
88
88
  x: number;
89
89
  y: number;
90
- }, c2: {
90
+ }>, c2: Readonly<{
91
91
  x: number;
92
92
  y: number;
93
- }, p1: {
93
+ }>, p1: Readonly<{
94
94
  x: number;
95
95
  y: number;
96
- }): readonly {
96
+ }>): readonly {
97
97
  x: number;
98
98
  y: number;
99
99
  }[];
100
- declare function drawGlyphOutline(outline: GlyphOutline, glyphMatrix: Matrix, color: Color, rasteriser: PageRasteriser): void;
100
+ declare function drawGlyphOutline(outline: GlyphOutline, glyphMatrix: Matrix, color: Readonly<Color>, rasteriser: Readonly<PageRasteriser>): void;
101
101
  declare function glyphOutlineSubpaths(outline: GlyphOutline, matrix: Matrix): readonly RasterSubpath[];
102
102
  //#endregion
103
103
  export { PageRasteriser, RasterDrawOp, RasterFillRectOp, RasterFillSpec, RasterImageOp, RasterMatrix, RasterPageGeometry, RasterPathOp, RasterPathSegment, RasterRegionPt, RasterStrokeSpec, RasterSubpath, RenderPdfPageOptions, drawGlyphOutline, flattenCubic, glyphOutlineSubpaths, renderPdfPage };
package/dist/raster.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import { PdfDiagnosticSink } from "./diagnostics.js";
2
2
  import { r as Matrix } from "./matrix-B7_SBKQ5.js";
3
- import { n as GlyphOutline } from "./glyf-contours-C0epBNqP.js";
3
+ import { n as GlyphOutline } from "./glyf-contours-B1PsI9oA.js";
4
4
  import { Color } from "document-schema.js";
5
5
  //#region src/raster.d.ts
6
6
  type RasterMatrix = readonly [number, number, number, number, number, number];
@@ -80,24 +80,24 @@ interface RenderPdfPageOptions {
80
80
  readonly sink?: PdfDiagnosticSink;
81
81
  readonly signal?: AbortSignal;
82
82
  }
83
- declare function renderPdfPage(pdfBytes: Uint8Array<ArrayBuffer>, pageIndex: number, options: RenderPdfPageOptions, rasteriser: PageRasteriser): Uint8Array<ArrayBuffer> | Promise<Uint8Array<ArrayBuffer>>;
84
- declare function flattenCubic(p0: {
83
+ declare function renderPdfPage(pdfBytes: Uint8Array<ArrayBuffer>, pageIndex: number, options: RenderPdfPageOptions, rasteriser: Readonly<PageRasteriser>): Uint8Array<ArrayBuffer> | Promise<Uint8Array<ArrayBuffer>>;
84
+ declare function flattenCubic(p0: Readonly<{
85
85
  x: number;
86
86
  y: number;
87
- }, c1: {
87
+ }>, c1: Readonly<{
88
88
  x: number;
89
89
  y: number;
90
- }, c2: {
90
+ }>, c2: Readonly<{
91
91
  x: number;
92
92
  y: number;
93
- }, p1: {
93
+ }>, p1: Readonly<{
94
94
  x: number;
95
95
  y: number;
96
- }): readonly {
96
+ }>): readonly {
97
97
  x: number;
98
98
  y: number;
99
99
  }[];
100
- declare function drawGlyphOutline(outline: GlyphOutline, glyphMatrix: Matrix, color: Color, rasteriser: PageRasteriser): void;
100
+ declare function drawGlyphOutline(outline: GlyphOutline, glyphMatrix: Matrix, color: Readonly<Color>, rasteriser: Readonly<PageRasteriser>): void;
101
101
  declare function glyphOutlineSubpaths(outline: GlyphOutline, matrix: Matrix): readonly RasterSubpath[];
102
102
  //#endregion
103
103
  export { PageRasteriser, RasterDrawOp, RasterFillRectOp, RasterFillSpec, RasterImageOp, RasterMatrix, RasterPageGeometry, RasterPathOp, RasterPathSegment, RasterRegionPt, RasterStrokeSpec, RasterSubpath, RenderPdfPageOptions, drawGlyphOutline, flattenCubic, glyphOutlineSubpaths, renderPdfPage };
package/dist/raster.js CHANGED
@@ -16,13 +16,16 @@ import { normalizeRotation, pageRotationTransform } from "./read.js";
16
16
  import { parseGlyf } from "./glyf.js";
17
17
  import { decodeGlyphOutline } from "./glyf-contours.js";
18
18
  //#region src/raster.ts
19
+ const PIXEL_ROUNDING_EPSILON = 1e-9;
20
+ const POINTS_PER_INCH = 72;
21
+ const EXTENT_ZERO_EPSILON = 1e-9;
19
22
  function regionPixels(extentPt, scale) {
20
- return Math.max(1, Math.ceil(extentPt * scale - 1e-9));
23
+ return Math.max(1, Math.ceil(extentPt * scale - PIXEL_ROUNDING_EPSILON));
21
24
  }
22
25
  function renderPdfPage(pdfBytes, pageIndex, options, rasteriser) {
23
26
  const sink = options.sink ?? NOOP_DIAGNOSTIC_SINK;
24
27
  if (options.scale !== void 0 && options.dpi !== void 0) throw new Error("renderPdfPage accepts at most one of scale and dpi; they name the same factor in different units (dpi = 72 x scale)");
25
- const scale = options.dpi !== void 0 ? options.dpi / 72 : options.scale;
28
+ const scale = options.dpi !== void 0 ? options.dpi / POINTS_PER_INCH : options.scale;
26
29
  if (scale !== void 0 && !(scale > 0)) throw new Error(`renderPdfPage requires a positive scale factor (received scale ${options.scale}, dpi ${options.dpi})`);
27
30
  const pixelsPerPt = scale ?? 1;
28
31
  if (options.clipPt !== void 0 && (!(options.clipPt.widthPt > 0) || !(options.clipPt.heightPt > 0))) throw new Error("renderPdfPage clipPt must carry positive widthPt and heightPt; a zero-extent region has no pixels to render");
@@ -194,6 +197,7 @@ function drawRect(item, matrix, pixelsPerPt, rasteriser) {
194
197
  stroke: strokeSpec(item.stroke, void 0, pixelsPerPt)
195
198
  });
196
199
  }
200
+ const ELLIPSE_QUADRANT_COUNT = 4;
197
201
  function drawEllipse(item, matrix, pixelsPerPt, rasteriser) {
198
202
  const cx = item.xPt + item.widthPt / 2;
199
203
  const cy = item.yPt + item.heightPt / 2;
@@ -223,8 +227,8 @@ function drawEllipse(item, matrix, pixelsPerPt, rasteriser) {
223
227
  });
224
228
  const start = transformed(cardinalPoints[0]);
225
229
  const segments = [];
226
- for (let i = 0; i < 4; i++) {
227
- const end = transformed(cardinalPoints[(i + 1) % 4]);
230
+ for (let i = 0; i < ELLIPSE_QUADRANT_COUNT; i++) {
231
+ const end = transformed(cardinalPoints[(i + 1) % ELLIPSE_QUADRANT_COUNT]);
228
232
  const c1 = transformed(controls[i * 2]);
229
233
  const c2 = transformed(controls[i * 2 + 1]);
230
234
  segments.push({
@@ -401,12 +405,13 @@ function drawImage(image, ctm, interpretToDeviceMatrix, rasteriser) {
401
405
  matrix
402
406
  });
403
407
  }
408
+ const DASHED_STROKE_WIDTH_MULTIPLE = 3;
404
409
  function strokeSpec(stroke, style, pixelsPerPt) {
405
410
  const widthPx = stroke.widthPt * pixelsPerPt;
406
411
  if (style === "dashed") return {
407
412
  color: stroke.color,
408
413
  widthPx,
409
- dashPx: [widthPx * 3, widthPx * 3]
414
+ dashPx: [widthPx * DASHED_STROKE_WIDTH_MULTIPLE, widthPx * DASHED_STROKE_WIDTH_MULTIPLE]
410
415
  };
411
416
  return {
412
417
  color: stroke.color,
@@ -474,6 +479,7 @@ function flattenCubic(p0, c1, c2, p1) {
474
479
  flatten(p0, c1, c2, p1, 0);
475
480
  return points;
476
481
  }
482
+ const CFF_HEADER_SIZE = 4;
477
483
  function openEmbeddedProgram(descriptorOwner, resolver) {
478
484
  const descriptor = resolver.resolveDict(dictGet(descriptorOwner, "FontDescriptor"));
479
485
  if (descriptor === void 0) return { kind: "absent" };
@@ -481,7 +487,7 @@ function openEmbeddedProgram(descriptorOwner, resolver) {
481
487
  const stream = resolver.resolve(dictGet(descriptor, key));
482
488
  if (stream?.kind !== "stream") continue;
483
489
  const bytes = decodeStream(stream.raw, stream.dict, NOOP_DIAGNOSTIC_SINK).bytes;
484
- if (bytes[0] === 1 && bytes[1] === 0 && bytes[2] === 4) return { kind: "cff" };
490
+ if (bytes[0] === 1 && bytes[1] === 0 && bytes[2] === CFF_HEADER_SIZE) return { kind: "cff" };
485
491
  const sfnt = parseSfnt(bytes);
486
492
  if (sfnt === void 0) continue;
487
493
  if (sfnt.tables.has("CFF ")) return { kind: "cff" };
@@ -513,6 +519,7 @@ function resolveTextOutlineFace(fontResourceName, resources, resolver, fontResol
513
519
  outlineFaces.set(fontDict, face);
514
520
  return face;
515
521
  }
522
+ const BITS_PER_BYTE = 8;
516
523
  function buildTextOutlineFace(fontDict, resolver, fontResolver, fontResourceName, resources, sink) {
517
524
  const faceName = asName(dictGet(fontDict, "BaseFont")) ?? asName(dictGet(fontDict, "Subtype")) ?? "font";
518
525
  const unavailable = (reason) => {
@@ -547,12 +554,12 @@ function buildTextOutlineFace(fontDict, resolver, fontResolver, fontResourceName
547
554
  if (cidToGidMap?.kind === "stream") {
548
555
  const decodedBytes = decodeStream(cidToGidMap.raw, cidToGidMap.dict, NOOP_DIAGNOSTIC_SINK).bytes;
549
556
  const entries = [];
550
- for (let i = 0; i + 1 < decodedBytes.length; i += 2) entries.push(decodedBytes[i] << 8 | decodedBytes[i + 1]);
557
+ for (let i = 0; i + 1 < decodedBytes.length; i += 2) entries.push(decodedBytes[i] << BITS_PER_BYTE | decodedBytes[i + 1]);
551
558
  return {
552
559
  glyf: program.face.glyf,
553
560
  unitsPerEm: program.face.unitsPerEm,
554
561
  glyphIdOf: (codes, offset) => {
555
- const cid = codes[offset] << 8 | codes[offset + 1];
562
+ const cid = codes[offset] << BITS_PER_BYTE | codes[offset + 1];
556
563
  return entries[cid];
557
564
  }
558
565
  };
@@ -560,7 +567,7 @@ function buildTextOutlineFace(fontDict, resolver, fontResolver, fontResourceName
560
567
  return {
561
568
  glyf: program.face.glyf,
562
569
  unitsPerEm: program.face.unitsPerEm,
563
- glyphIdOf: (codes, offset) => codes[offset] << 8 | codes[offset + 1]
570
+ glyphIdOf: (codes, offset) => codes[offset] << BITS_PER_BYTE | codes[offset + 1]
564
571
  };
565
572
  }
566
573
  if (subtype === "TrueType") {
@@ -584,6 +591,7 @@ function buildTextOutlineFace(fontDict, resolver, fontResolver, fontResourceName
584
591
  }
585
592
  return unavailable(`a font of subtype ${subtype ?? "(none)"} (a Type3 glyph-procedure font has no static outline at all)`);
586
593
  }
594
+ const METRICS_PER_1000_SCALE = 1e3;
587
595
  function drawTextRun(item, fontResolver, resolver, outlineFaces, interpretToDeviceMatrix, rasteriser, sink) {
588
596
  const face = resolveTextOutlineFace(item.fontResourceName, item.resources, resolver, fontResolver, outlineFaces, sink);
589
597
  if (face === void 0) return;
@@ -596,10 +604,10 @@ function drawTextRun(item, fontResolver, resolver, outlineFaces, interpretToDevi
596
604
  placements.push({
597
605
  glyphId: face.glyphIdOf(item.codes, offset),
598
606
  advance: cumulative,
599
- positionX: (advance.vertical?.positionXPer1000 ?? 0) / 1e3,
600
- positionY: (advance.vertical?.positionYPer1000 ?? 0) / 1e3
607
+ positionX: (advance.vertical?.positionXPer1000 ?? 0) / METRICS_PER_1000_SCALE,
608
+ positionY: (advance.vertical?.positionYPer1000 ?? 0) / METRICS_PER_1000_SCALE
601
609
  });
602
- cumulative += (advance.vertical?.displacementPer1000 ?? advance.widthPer1000) / 1e3 * item.sizePt;
610
+ cumulative += (advance.vertical?.displacementPer1000 ?? advance.widthPer1000) / METRICS_PER_1000_SCALE * item.sizePt;
603
611
  offset += byteLength;
604
612
  }
605
613
  const startDeviceMatrix = multiplyMatrices(item.startMatrix, interpretToDeviceMatrix);
@@ -622,7 +630,7 @@ function drawTextRun(item, fontResolver, resolver, outlineFaces, interpretToDevi
622
630
  });
623
631
  const rawExtent = Math.hypot(rawEndPoint.x - startPoint.x, rawEndPoint.y - startPoint.y);
624
632
  const actualExtent = Math.hypot(endPoint.x - startPoint.x, endPoint.y - startPoint.y);
625
- const correction = rawExtent > 1e-9 ? actualExtent / rawExtent : 1;
633
+ const correction = rawExtent > EXTENT_ZERO_EPSILON ? actualExtent / rawExtent : 1;
626
634
  const firstPlacement = placements[0];
627
635
  const glyphScale = scaleMatrix(1 / face.unitsPerEm, 1 / face.unitsPerEm);
628
636
  for (const placement of placements) {
@@ -645,10 +653,12 @@ function drawGlyphOutline(outline, glyphMatrix, color, rasteriser) {
645
653
  }
646
654
  });
647
655
  }
656
+ const MIN_CONTOUR_POINTS = 3;
657
+ const QUADRATIC_TO_CUBIC_CONTROL_FRACTION = 2 / 3;
648
658
  function glyphOutlineSubpaths(outline, matrix) {
649
659
  const subpaths = [];
650
660
  for (const contour of outline.contours) {
651
- if (contour.length < 3) continue;
661
+ if (contour.length < MIN_CONTOUR_POINTS) continue;
652
662
  const firstOn = contour.findIndex((point) => point.onCurve);
653
663
  const contourPoints = contour.map((point) => ({
654
664
  x: point.x,
@@ -673,10 +683,10 @@ function glyphOutlineSubpaths(outline, matrix) {
673
683
  const p1 = applyMatrix(matrix, to);
674
684
  segments.push({
675
685
  kind: "cubic",
676
- c1xPx: p0.x + 2 / 3 * (q.x - p0.x),
677
- c1yPx: p0.y + 2 / 3 * (q.y - p0.y),
678
- c2xPx: p1.x + 2 / 3 * (q.x - p1.x),
679
- c2yPx: p1.y + 2 / 3 * (q.y - p1.y),
686
+ c1xPx: p0.x + QUADRATIC_TO_CUBIC_CONTROL_FRACTION * (q.x - p0.x),
687
+ c1yPx: p0.y + QUADRATIC_TO_CUBIC_CONTROL_FRACTION * (q.y - p0.y),
688
+ c2xPx: p1.x + QUADRATIC_TO_CUBIC_CONTROL_FRACTION * (q.x - p1.x),
689
+ c2yPx: p1.y + QUADRATIC_TO_CUBIC_CONTROL_FRACTION * (q.y - p1.y),
680
690
  xPx: p1.x,
681
691
  yPx: p1.y
682
692
  });
@@ -764,6 +774,7 @@ function rotatedRectBounds(rect, matrix) {
764
774
  maxY: Math.max(...ys)
765
775
  };
766
776
  }
777
+ const NEWLINE_BYTE = 10;
767
778
  function readPageContentBytes(page, resolver, sink) {
768
779
  const contentsObj = resolver.resolve(dictGet(page, "Contents"));
769
780
  if (contentsObj?.kind === "stream") return decodeStream(contentsObj.raw, contentsObj.dict, sink).bytes;
@@ -771,7 +782,7 @@ function readPageContentBytes(page, resolver, sink) {
771
782
  const chunks = [];
772
783
  for (const entry of contentsObj.items) {
773
784
  const streamObj = resolver.resolve(entry);
774
- if (streamObj?.kind === "stream") chunks.push(decodeStream(streamObj.raw, streamObj.dict, sink).bytes, new Uint8Array([10]));
785
+ if (streamObj?.kind === "stream") chunks.push(decodeStream(streamObj.raw, streamObj.dict, sink).bytes, new Uint8Array([NEWLINE_BYTE]));
775
786
  }
776
787
  return concatBytes(chunks);
777
788
  }