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
package/dist/filters.js CHANGED
@@ -5,6 +5,8 @@ import { decodeCcittFax } from "./image/ccitt.js";
5
5
  import { decodeJbig2Embedded } from "./image/jbig2.js";
6
6
  import { applyPredictor, readPredictorParams } from "./predictors.js";
7
7
  //#region src/filters.ts
8
+ const BITS_PER_BYTE = 8;
9
+ const BYTE_MASK = 255;
8
10
  function decodeStream(raw, dict, sink, resolve) {
9
11
  const filters = filterNames(dict);
10
12
  const parms = decodeParmsList(dict, filters.length);
@@ -102,7 +104,7 @@ function jbig2Decode(data, parm, dict, sink, resolve) {
102
104
  }
103
105
  });
104
106
  return {
105
- bytes: Uint8Array.from(image.bytes, (byte) => byte ^ 255),
107
+ bytes: Uint8Array.from(image.bytes, (byte) => byte ^ BYTE_MASK),
106
108
  globals
107
109
  };
108
110
  } catch (error) {
@@ -145,6 +147,9 @@ function decodeParmsList(dict, count) {
145
147
  const LZW_CLEAR_TABLE = 256;
146
148
  const LZW_EOD = 257;
147
149
  const LZW_INITIAL_CODE_WIDTH = 9;
150
+ const LZW_CODE_WIDTH_10 = 10;
151
+ const LZW_CODE_WIDTH_11 = 11;
152
+ const LZW_CODE_WIDTH_12 = 12;
148
153
  const LZW_FIRST_NEW_CODE = 258;
149
154
  function initialLzwDictionary() {
150
155
  return Array.from({ length: 256 }, (_, i) => new Uint8Array([i]));
@@ -168,9 +173,9 @@ function lzwDecode(data, earlyChange, sink) {
168
173
  const readCode = () => {
169
174
  while (bitCount < codeWidth) {
170
175
  if (pos >= data.length) return;
171
- bitBuffer = bitBuffer << 8 | data[pos];
176
+ bitBuffer = bitBuffer << BITS_PER_BYTE | data[pos];
172
177
  pos++;
173
- bitCount += 8;
178
+ bitCount += BITS_PER_BYTE;
174
179
  }
175
180
  const value = bitBuffer >>> bitCount - codeWidth & (1 << codeWidth) - 1;
176
181
  bitCount -= codeWidth;
@@ -202,9 +207,9 @@ function lzwDecode(data, earlyChange, sink) {
202
207
  if (prevEntry !== void 0) {
203
208
  dict[nextCode] = concatTwo(prevEntry, new Uint8Array([entry[0] ?? 0]));
204
209
  nextCode++;
205
- if (nextCode + bias === 512) codeWidth = 10;
206
- else if (nextCode + bias === 1024) codeWidth = 11;
207
- else if (nextCode + bias === 2048) codeWidth = 12;
210
+ if (nextCode + bias === 2 ** LZW_INITIAL_CODE_WIDTH) codeWidth = LZW_CODE_WIDTH_10;
211
+ else if (nextCode + bias === 2 ** LZW_CODE_WIDTH_10) codeWidth = LZW_CODE_WIDTH_11;
212
+ else if (nextCode + bias === 2 ** LZW_CODE_WIDTH_11) codeWidth = LZW_CODE_WIDTH_12;
208
213
  }
209
214
  prevEntry = entry;
210
215
  }
@@ -216,21 +221,26 @@ const ASCII85_END_MARKER = 126;
216
221
  const ASCII85_MIN_DIGIT = 33;
217
222
  const ASCII85_MAX_DIGIT = 117;
218
223
  const ASCII85_MAX_DIGIT_VALUE = 84;
224
+ const ASCII85_RADIX = 85;
225
+ const ASCII85_GROUP_DIGITS = 5;
226
+ const ASCII85_OPTIONAL_PREFIX_LT = 60;
227
+ const ASCII85_BYTE_3_SHIFT = 24;
228
+ const ASCII85_BYTE_2_SHIFT = 16;
219
229
  function ascii85GroupBytes(digits, byteCount) {
220
230
  let value = 0;
221
- for (const digit of digits) value = value * 85 + digit;
231
+ for (const digit of digits) value = value * ASCII85_RADIX + digit;
222
232
  return [
223
- value >>> 24 & 255,
224
- value >>> 16 & 255,
225
- value >>> 8 & 255,
226
- value & 255
233
+ value >>> ASCII85_BYTE_3_SHIFT & BYTE_MASK,
234
+ value >>> ASCII85_BYTE_2_SHIFT & BYTE_MASK,
235
+ value >>> BITS_PER_BYTE & BYTE_MASK,
236
+ value & BYTE_MASK
227
237
  ].slice(0, byteCount);
228
238
  }
229
239
  function ascii85Decode(data) {
230
240
  const out = [];
231
241
  let tuple = [];
232
242
  let i = 0;
233
- if (data.length >= 2 && data[0] === 60 && data[1] === 126) i = 2;
243
+ if (data.length >= 2 && data[0] === ASCII85_OPTIONAL_PREFIX_LT && data[1] === ASCII85_END_MARKER) i = 2;
234
244
  for (; i < data.length; i++) {
235
245
  const byte = data[i];
236
246
  if (byte === ASCII85_END_MARKER) break;
@@ -241,36 +251,46 @@ function ascii85Decode(data) {
241
251
  }
242
252
  if (byte < ASCII85_MIN_DIGIT || byte > ASCII85_MAX_DIGIT) continue;
243
253
  tuple.push(byte - ASCII85_MIN_DIGIT);
244
- if (tuple.length === 5) {
254
+ if (tuple.length === ASCII85_GROUP_DIGITS) {
245
255
  out.push(...ascii85GroupBytes(tuple, ASCII85_GROUP_BYTES));
246
256
  tuple = [];
247
257
  }
248
258
  }
249
259
  if (tuple.length > 1) {
250
260
  const padded = tuple.slice();
251
- while (padded.length < 5) padded.push(ASCII85_MAX_DIGIT_VALUE);
261
+ while (padded.length < ASCII85_GROUP_DIGITS) padded.push(ASCII85_MAX_DIGIT_VALUE);
252
262
  out.push(...ascii85GroupBytes(padded, tuple.length - 1));
253
263
  }
254
264
  return Uint8Array.from(out);
255
265
  }
266
+ const ASCII_DIGIT_ZERO = 48;
267
+ const ASCII_DIGIT_NINE = 57;
268
+ const ASCII_UPPER_A = 65;
269
+ const ASCII_UPPER_F = 70;
270
+ const ASCII_LOWER_A = 97;
271
+ const ASCII_LOWER_F = 102;
272
+ const HEX_LETTER_DIGIT_OFFSET = 10;
273
+ const ASCII_HEX_TERMINATOR = 62;
274
+ const HEX_NIBBLE_BITS = 4;
256
275
  function hexDigitValue(byte) {
257
- if (byte >= 48 && byte <= 57) return byte - 48;
258
- if (byte >= 65 && byte <= 70) return byte - 65 + 10;
259
- if (byte >= 97 && byte <= 102) return byte - 97 + 10;
276
+ if (byte >= ASCII_DIGIT_ZERO && byte <= ASCII_DIGIT_NINE) return byte - ASCII_DIGIT_ZERO;
277
+ if (byte >= ASCII_UPPER_A && byte <= ASCII_UPPER_F) return byte - ASCII_UPPER_A + HEX_LETTER_DIGIT_OFFSET;
278
+ if (byte >= ASCII_LOWER_A && byte <= ASCII_LOWER_F) return byte - ASCII_LOWER_A + HEX_LETTER_DIGIT_OFFSET;
260
279
  }
261
280
  function asciiHexDecode(data) {
262
281
  const digits = [];
263
282
  for (const byte of data) {
264
- if (byte === 62) break;
283
+ if (byte === ASCII_HEX_TERMINATOR) break;
265
284
  const value = hexDigitValue(byte);
266
285
  if (value !== void 0) digits.push(value);
267
286
  }
268
287
  if (digits.length % 2 === 1) digits.push(0);
269
288
  const out = new Uint8Array(digits.length / 2);
270
- for (let i = 0; i < out.length; i++) out[i] = digits[i * 2] << 4 | digits[i * 2 + 1];
289
+ for (let i = 0; i < out.length; i++) out[i] = digits[i * 2] << HEX_NIBBLE_BITS | digits[i * 2 + 1];
271
290
  return out;
272
291
  }
273
292
  const RUN_LENGTH_EOD = 128;
293
+ const RUN_LENGTH_REPEAT_COUNT_BASE = 257;
274
294
  function runLengthDecode(data) {
275
295
  const out = [];
276
296
  let i = 0;
@@ -282,7 +302,7 @@ function runLengthDecode(data) {
282
302
  const count = length + 1;
283
303
  for (let j = 0; j < count && i < data.length; j++, i++) out.push(data[i]);
284
304
  } else {
285
- const count = 257 - length;
305
+ const count = RUN_LENGTH_REPEAT_COUNT_BASE - length;
286
306
  const byte = data[i] ?? 0;
287
307
  i++;
288
308
  for (let j = 0; j < count; j++) out.push(byte);
@@ -9,8 +9,9 @@ var FontFaceParseError = class extends Error {
9
9
  }
10
10
  };
11
11
  const SFNT_VERSION_COLLECTION = 1953784678;
12
+ const SFNT_VERSION_TAG_BYTES = 4;
12
13
  function isTrueTypeCollection(bytes) {
13
- return require_sfnt.hasBytes(bytes, 0, 4) && require_sfnt.u32(bytes, 0) === SFNT_VERSION_COLLECTION;
14
+ return require_sfnt.hasBytes(bytes, 0, SFNT_VERSION_TAG_BYTES) && require_sfnt.u32(bytes, 0) === SFNT_VERSION_COLLECTION;
14
15
  }
15
16
  const OS2_FS_SELECTION_ITALIC = 1;
16
17
  const OS2_FS_SELECTION_BOLD = 32;
package/dist/font-face.js CHANGED
@@ -8,8 +8,9 @@ var FontFaceParseError = class extends Error {
8
8
  }
9
9
  };
10
10
  const SFNT_VERSION_COLLECTION = 1953784678;
11
+ const SFNT_VERSION_TAG_BYTES = 4;
11
12
  function isTrueTypeCollection(bytes) {
12
- return hasBytes(bytes, 0, 4) && u32(bytes, 0) === SFNT_VERSION_COLLECTION;
13
+ return hasBytes(bytes, 0, SFNT_VERSION_TAG_BYTES) && u32(bytes, 0) === SFNT_VERSION_COLLECTION;
13
14
  }
14
15
  const OS2_FS_SELECTION_ITALIC = 1;
15
16
  const OS2_FS_SELECTION_BOLD = 32;
@@ -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_objects = require("./objects.cjs");
4
4
  const require_filters = require("./filters.cjs");
5
5
  const require_builtin_encoding = require("./builtin-encoding.cjs");
@@ -7,6 +7,7 @@ const require_cmap = require("./cmap.cjs");
7
7
  const require_fonts = require("./fonts.cjs");
8
8
  const require_font_style = require("./font-style.cjs");
9
9
  //#region src/font-read.ts
10
+ const BITS_PER_BYTE = 8;
10
11
  const SYMBOLIC_FLAG_BIT = 4;
11
12
  const ITALIC_FLAG_BIT = 64;
12
13
  const FORCE_BOLD_FLAG_BIT = 1 << 18;
@@ -150,6 +151,7 @@ function buildSimpleFont(fontDict, context) {
150
151
  decodeToUnicode
151
152
  };
152
153
  }
154
+ const W_RANGE_ENTRY_COUNT = 3;
153
155
  function readCidWidths(w) {
154
156
  const map = /* @__PURE__ */ new Map();
155
157
  if (w === void 0) return map;
@@ -171,7 +173,7 @@ function readCidWidths(w) {
171
173
  const last = require_objects.asNumber(next);
172
174
  const width = require_objects.asNumber(w[i + 2]);
173
175
  if (last !== void 0 && width !== void 0) for (let cid = first; cid <= last; cid++) map.set(cid, width);
174
- i += 3;
176
+ i += W_RANGE_ENTRY_COUNT;
175
177
  }
176
178
  }
177
179
  return map;
@@ -182,6 +184,10 @@ const DEFAULT_VERTICAL_DISPLACEMENT_Y = -1e3;
182
184
  const DW2_ENTRY_COUNT = 2;
183
185
  const W2_TRIPLET_LENGTH = 3;
184
186
  const VERTICAL_WRITING_MODE = 1;
187
+ const W2_RANGE_W1Y_OFFSET = 2;
188
+ const W2_RANGE_VX_OFFSET = 3;
189
+ const W2_RANGE_VY_OFFSET = 4;
190
+ const W2_RANGE_ENTRY_COUNT = 5;
185
191
  function readCidVerticalMetrics(w2) {
186
192
  const map = /* @__PURE__ */ new Map();
187
193
  if (w2 === void 0) return map;
@@ -202,9 +208,9 @@ function readCidVerticalMetrics(w2) {
202
208
  continue;
203
209
  }
204
210
  const last = require_objects.asNumber(next);
205
- const entry = verticalEntryFrom(require_objects.asNumber(w2[i + 2]), require_objects.asNumber(w2[i + 3]), require_objects.asNumber(w2[i + 4]));
211
+ const entry = verticalEntryFrom(require_objects.asNumber(w2[i + W2_RANGE_W1Y_OFFSET]), require_objects.asNumber(w2[i + W2_RANGE_VX_OFFSET]), require_objects.asNumber(w2[i + W2_RANGE_VY_OFFSET]));
206
212
  if (last !== void 0 && entry !== void 0) for (let cid = first; cid <= last; cid++) map.set(cid, entry);
207
- i += 5;
213
+ i += W2_RANGE_ENTRY_COUNT;
208
214
  }
209
215
  return map;
210
216
  }
@@ -265,7 +271,7 @@ function buildCompositeFont(fontDict, context) {
265
271
  let unmapped = 0;
266
272
  for (let i = 0; i + 1 < codes.length; i += 2) {
267
273
  glyphCount++;
268
- const cid = (codes[i] ?? 0) << 8 | (codes[i + 1] ?? 0);
274
+ const cid = (codes[i] ?? 0) << BITS_PER_BYTE | (codes[i + 1] ?? 0);
269
275
  const mapped = toUnicode?.lookup(cid);
270
276
  if (mapped !== void 0) {
271
277
  out += mapped;
@@ -313,7 +319,7 @@ function createFontResolver(context) {
313
319
  const font = resolve(fontResourceName, resources);
314
320
  if (font === void 0) return;
315
321
  const byteLengthConsumed = font.composite ? 2 : 1;
316
- const code = font.composite ? (codes[byteOffset] ?? 0) << 8 | (codes[byteOffset + 1] ?? 0) : codes[byteOffset] ?? 0;
322
+ const code = font.composite ? (codes[byteOffset] ?? 0) << BITS_PER_BYTE | (codes[byteOffset + 1] ?? 0) : codes[byteOffset] ?? 0;
317
323
  const vertical = font.verticalMetricsOf?.(code);
318
324
  return {
319
325
  widthPer1000: font.widthOf(code),
package/dist/font-read.js CHANGED
@@ -1,4 +1,4 @@
1
- import { c as glyphNameToUnicode, f as symbolGlyphName, m as zapfDingbatsGlyphName, n as widthOfCode, p as winAnsiGlyphName, u as namedEncodingGlyphName } from "./afm-widths-blUDDjlI.js";
1
+ import { c as glyphNameToUnicode, f as symbolGlyphName, m as zapfDingbatsGlyphName, n as widthOfCode, p as winAnsiGlyphName, u as namedEncodingGlyphName } from "./afm-widths-B_IGbGky.js";
2
2
  import { asArray, asName, asNumber, dictGet, isName } from "./objects.js";
3
3
  import { decodeStream } from "./filters.js";
4
4
  import { readFontProgramEncoding } from "./builtin-encoding.js";
@@ -6,6 +6,7 @@ import { parseToUnicodeCMap } from "./cmap.js";
6
6
  import { resolveStandardFont } from "./fonts.js";
7
7
  import { styleFromBaseFontName } from "./font-style.js";
8
8
  //#region src/font-read.ts
9
+ const BITS_PER_BYTE = 8;
9
10
  const SYMBOLIC_FLAG_BIT = 4;
10
11
  const ITALIC_FLAG_BIT = 64;
11
12
  const FORCE_BOLD_FLAG_BIT = 1 << 18;
@@ -149,6 +150,7 @@ function buildSimpleFont(fontDict, context) {
149
150
  decodeToUnicode
150
151
  };
151
152
  }
153
+ const W_RANGE_ENTRY_COUNT = 3;
152
154
  function readCidWidths(w) {
153
155
  const map = /* @__PURE__ */ new Map();
154
156
  if (w === void 0) return map;
@@ -170,7 +172,7 @@ function readCidWidths(w) {
170
172
  const last = asNumber(next);
171
173
  const width = asNumber(w[i + 2]);
172
174
  if (last !== void 0 && width !== void 0) for (let cid = first; cid <= last; cid++) map.set(cid, width);
173
- i += 3;
175
+ i += W_RANGE_ENTRY_COUNT;
174
176
  }
175
177
  }
176
178
  return map;
@@ -181,6 +183,10 @@ const DEFAULT_VERTICAL_DISPLACEMENT_Y = -1e3;
181
183
  const DW2_ENTRY_COUNT = 2;
182
184
  const W2_TRIPLET_LENGTH = 3;
183
185
  const VERTICAL_WRITING_MODE = 1;
186
+ const W2_RANGE_W1Y_OFFSET = 2;
187
+ const W2_RANGE_VX_OFFSET = 3;
188
+ const W2_RANGE_VY_OFFSET = 4;
189
+ const W2_RANGE_ENTRY_COUNT = 5;
184
190
  function readCidVerticalMetrics(w2) {
185
191
  const map = /* @__PURE__ */ new Map();
186
192
  if (w2 === void 0) return map;
@@ -201,9 +207,9 @@ function readCidVerticalMetrics(w2) {
201
207
  continue;
202
208
  }
203
209
  const last = asNumber(next);
204
- const entry = verticalEntryFrom(asNumber(w2[i + 2]), asNumber(w2[i + 3]), asNumber(w2[i + 4]));
210
+ const entry = verticalEntryFrom(asNumber(w2[i + W2_RANGE_W1Y_OFFSET]), asNumber(w2[i + W2_RANGE_VX_OFFSET]), asNumber(w2[i + W2_RANGE_VY_OFFSET]));
205
211
  if (last !== void 0 && entry !== void 0) for (let cid = first; cid <= last; cid++) map.set(cid, entry);
206
- i += 5;
212
+ i += W2_RANGE_ENTRY_COUNT;
207
213
  }
208
214
  return map;
209
215
  }
@@ -264,7 +270,7 @@ function buildCompositeFont(fontDict, context) {
264
270
  let unmapped = 0;
265
271
  for (let i = 0; i + 1 < codes.length; i += 2) {
266
272
  glyphCount++;
267
- const cid = (codes[i] ?? 0) << 8 | (codes[i + 1] ?? 0);
273
+ const cid = (codes[i] ?? 0) << BITS_PER_BYTE | (codes[i + 1] ?? 0);
268
274
  const mapped = toUnicode?.lookup(cid);
269
275
  if (mapped !== void 0) {
270
276
  out += mapped;
@@ -312,7 +318,7 @@ function createFontResolver(context) {
312
318
  const font = resolve(fontResourceName, resources);
313
319
  if (font === void 0) return;
314
320
  const byteLengthConsumed = font.composite ? 2 : 1;
315
- const code = font.composite ? (codes[byteOffset] ?? 0) << 8 | (codes[byteOffset + 1] ?? 0) : codes[byteOffset] ?? 0;
321
+ const code = font.composite ? (codes[byteOffset] ?? 0) << BITS_PER_BYTE | (codes[byteOffset + 1] ?? 0) : codes[byteOffset] ?? 0;
316
322
  const vertical = font.verticalMetricsOf?.(code);
317
323
  return {
318
324
  widthPer1000: font.widthOf(code),
@@ -5,35 +5,53 @@ const HEAD_TABLE_SIZE = 54;
5
5
  const HEAD_MAGIC_NUMBER = 1594834165;
6
6
  const MIN_UNITS_PER_EM = 16;
7
7
  const MAX_UNITS_PER_EM = 16384;
8
+ const HEAD_CHECKSUM_ADJUSTMENT_OFFSET = 8;
9
+ const HEAD_MAGIC_NUMBER_OFFSET = 12;
10
+ const HEAD_UNITS_PER_EM_OFFSET = 18;
11
+ const HEAD_X_MIN_OFFSET = 36;
12
+ const HEAD_Y_MIN_OFFSET = 38;
13
+ const HEAD_X_MAX_OFFSET = 40;
14
+ const HEAD_Y_MAX_OFFSET = 42;
15
+ const HEAD_MAC_STYLE_OFFSET = 44;
16
+ const HEAD_INDEX_TO_LOC_FORMAT_OFFSET = 50;
8
17
  function parseHead(font) {
9
18
  const bytes = require_sfnt.sfntTableBytes(font, "head");
10
19
  if (bytes === void 0 || !require_sfnt.hasBytes(bytes, 0, HEAD_TABLE_SIZE)) return;
11
- if (require_sfnt.u32(bytes, 12) !== HEAD_MAGIC_NUMBER) return;
12
- const unitsPerEm = require_sfnt.u16(bytes, 18);
20
+ if (require_sfnt.u32(bytes, HEAD_MAGIC_NUMBER_OFFSET) !== HEAD_MAGIC_NUMBER) return;
21
+ const unitsPerEm = require_sfnt.u16(bytes, HEAD_UNITS_PER_EM_OFFSET);
13
22
  if (unitsPerEm < MIN_UNITS_PER_EM || unitsPerEm > MAX_UNITS_PER_EM) return;
14
- const indexToLocFormat = require_sfnt.i16(bytes, 50);
23
+ const indexToLocFormat = require_sfnt.i16(bytes, HEAD_INDEX_TO_LOC_FORMAT_OFFSET);
15
24
  if (indexToLocFormat !== 0 && indexToLocFormat !== 1) return;
16
25
  return {
17
26
  unitsPerEm,
18
- checkSumAdjustment: require_sfnt.u32(bytes, 8),
19
- xMin: require_sfnt.i16(bytes, 36),
20
- yMin: require_sfnt.i16(bytes, 38),
21
- xMax: require_sfnt.i16(bytes, 40),
22
- yMax: require_sfnt.i16(bytes, 42),
27
+ checkSumAdjustment: require_sfnt.u32(bytes, HEAD_CHECKSUM_ADJUSTMENT_OFFSET),
28
+ xMin: require_sfnt.i16(bytes, HEAD_X_MIN_OFFSET),
29
+ yMin: require_sfnt.i16(bytes, HEAD_Y_MIN_OFFSET),
30
+ xMax: require_sfnt.i16(bytes, HEAD_X_MAX_OFFSET),
31
+ yMax: require_sfnt.i16(bytes, HEAD_Y_MAX_OFFSET),
23
32
  indexToLocFormat,
24
- macStyle: require_sfnt.u16(bytes, 44)
33
+ macStyle: require_sfnt.u16(bytes, HEAD_MAC_STYLE_OFFSET)
25
34
  };
26
35
  }
27
36
  const MAXP_HEADER_SIZE = 6;
37
+ const MAXP_NUM_GLYPHS_OFFSET = 4;
28
38
  function parseMaxp(font) {
29
39
  const bytes = require_sfnt.sfntTableBytes(font, "maxp");
30
40
  if (bytes === void 0 || !require_sfnt.hasBytes(bytes, 0, MAXP_HEADER_SIZE)) return;
31
- return { numGlyphs: require_sfnt.u16(bytes, 4) };
41
+ return { numGlyphs: require_sfnt.u16(bytes, MAXP_NUM_GLYPHS_OFFSET) };
32
42
  }
33
43
  const OS2_VERSION_0_SIZE = 78;
34
44
  const OS2_VERSION_2_SIZE = 96;
35
45
  const OS2_VERSION_WITH_HEIGHTS = 2;
36
46
  const OS2_PANOSE_OFFSET = 32;
47
+ const OS2_FS_SELECTION_OFFSET = 62;
48
+ const OS2_S_TYPO_ASCENDER_OFFSET = 68;
49
+ const OS2_S_TYPO_DESCENDER_OFFSET = 70;
50
+ const OS2_S_TYPO_LINE_GAP_OFFSET = 72;
51
+ const OS2_US_WIN_ASCENT_OFFSET = 74;
52
+ const OS2_US_WIN_DESCENT_OFFSET = 76;
53
+ const OS2_SX_HEIGHT_OFFSET = 86;
54
+ const OS2_S_CAP_HEIGHT_OFFSET = 88;
37
55
  function parseOs2(font) {
38
56
  const bytes = require_sfnt.sfntTableBytes(font, "OS/2");
39
57
  if (bytes === void 0 || !require_sfnt.hasBytes(bytes, 0, OS2_VERSION_0_SIZE)) return;
@@ -41,27 +59,30 @@ function parseOs2(font) {
41
59
  const hasHeights = version >= OS2_VERSION_WITH_HEIGHTS && require_sfnt.hasBytes(bytes, 0, OS2_VERSION_2_SIZE);
42
60
  return {
43
61
  version,
44
- fsSelection: require_sfnt.u16(bytes, 62),
62
+ fsSelection: require_sfnt.u16(bytes, OS2_FS_SELECTION_OFFSET),
45
63
  panose: [...bytes.subarray(OS2_PANOSE_OFFSET, 42)],
46
- sTypoAscender: require_sfnt.i16(bytes, 68),
47
- sTypoDescender: require_sfnt.i16(bytes, 70),
48
- sTypoLineGap: require_sfnt.i16(bytes, 72),
49
- usWinAscent: require_sfnt.u16(bytes, 74),
50
- usWinDescent: require_sfnt.u16(bytes, 76),
51
- sxHeight: hasHeights ? require_sfnt.i16(bytes, 86) : void 0,
52
- sCapHeight: hasHeights ? require_sfnt.i16(bytes, 88) : void 0
64
+ sTypoAscender: require_sfnt.i16(bytes, OS2_S_TYPO_ASCENDER_OFFSET),
65
+ sTypoDescender: require_sfnt.i16(bytes, OS2_S_TYPO_DESCENDER_OFFSET),
66
+ sTypoLineGap: require_sfnt.i16(bytes, OS2_S_TYPO_LINE_GAP_OFFSET),
67
+ usWinAscent: require_sfnt.u16(bytes, OS2_US_WIN_ASCENT_OFFSET),
68
+ usWinDescent: require_sfnt.u16(bytes, OS2_US_WIN_DESCENT_OFFSET),
69
+ sxHeight: hasHeights ? require_sfnt.i16(bytes, OS2_SX_HEIGHT_OFFSET) : void 0,
70
+ sCapHeight: hasHeights ? require_sfnt.i16(bytes, OS2_S_CAP_HEIGHT_OFFSET) : void 0
53
71
  };
54
72
  }
55
73
  const POST_HEADER_SIZE = 32;
56
74
  const FIXED_16_16_SCALE = 65536;
75
+ const POST_ITALIC_ANGLE_OFFSET = 4;
76
+ const POST_UNDERLINE_POSITION_OFFSET = 8;
77
+ const POST_UNDERLINE_THICKNESS_OFFSET = 10;
57
78
  function parsePost(font) {
58
79
  const bytes = require_sfnt.sfntTableBytes(font, "post");
59
80
  if (bytes === void 0 || !require_sfnt.hasBytes(bytes, 0, POST_HEADER_SIZE)) return;
60
81
  return {
61
82
  version: require_sfnt.u32(bytes, 0),
62
- italicAngle: require_sfnt.i32(bytes, 4) / FIXED_16_16_SCALE,
63
- underlinePosition: require_sfnt.i16(bytes, 8),
64
- underlineThickness: require_sfnt.i16(bytes, 10)
83
+ italicAngle: require_sfnt.i32(bytes, POST_ITALIC_ANGLE_OFFSET) / FIXED_16_16_SCALE,
84
+ underlinePosition: require_sfnt.i16(bytes, POST_UNDERLINE_POSITION_OFFSET),
85
+ underlineThickness: require_sfnt.i16(bytes, POST_UNDERLINE_THICKNESS_OFFSET)
65
86
  };
66
87
  }
67
88
  const MAC_STANDARD_GLYPH_ORDER = ".notdef .null nonmarkingreturn space exclam quotedbl numbersign dollar percent ampersand quotesingle parenleft parenright asterisk plus comma hyphen period slash zero one two three four five six seven eight nine colon semicolon less equal greater question at A B C D E F G H I J K L M N O P Q R S T U V W X Y Z bracketleft backslash bracketright asciicircum underscore grave a b c d e f g h i j k l m n o p q r s t u v w x y z braceleft bar braceright asciitilde Adieresis Aring Ccedilla Eacute Ntilde Odieresis Udieresis aacute agrave acircumflex adieresis atilde aring ccedilla eacute egrave ecircumflex edieresis iacute igrave icircumflex idieresis ntilde oacute ograve ocircumflex odieresis otilde uacute ugrave ucircumflex udieresis dagger degree cent sterling section bullet paragraph germandbls registered copyright trademark acute dieresis notequal AE Oslash infinity plusminus lessequal greaterequal yen mu partialdiff summation product pi integral ordfeminine ordmasculine Omega ae oslash questiondown exclamdown logicalnot radical florin approxequal Delta guillemotleft guillemotright ellipsis nonbreakingspace Agrave Atilde Otilde OE oe endash emdash quotedblleft quotedblright quoteleft quoteright divide lozenge ydieresis Ydieresis fraction currency guilsinglleft guilsinglright fi fl daggerdbl periodcentered quotesinglbase quotedblbase perthousand Acircumflex Ecircumflex Aacute Edieresis Egrave Iacute Icircumflex Idieresis Igrave Oacute Ocircumflex apple Ograve Uacute Ucircumflex Ugrave dotlessi circumflex tilde macron breve dotaccent ring cedilla hungarumlaut ogonek caron Lslash lslash Scaron scaron Zcaron zcaron brokenbar Eth eth Yacute yacute Thorn thorn minus multiply onesuperior twosuperior threesuperior onehalf onequarter threequarters franc Gbreve gbreve Idotaccent Scedilla scedilla Cacute cacute Ccaron ccaron dcroat".split(" ");
@@ -95,6 +116,10 @@ function parsePostGlyphNames(font) {
95
116
  }
96
117
  const NAME_HEADER_SIZE = 6;
97
118
  const NAME_RECORD_SIZE = 12;
119
+ const NAME_HEADER_STORAGE_OFFSET_FIELD_OFFSET = 4;
120
+ const NAME_RECORD_NAME_ID_OFFSET = 6;
121
+ const NAME_RECORD_LENGTH_OFFSET = 8;
122
+ const NAME_RECORD_STRING_OFFSET_FIELD_OFFSET = 10;
98
123
  const NAME_ID_FAMILY = 1;
99
124
  const NAME_ID_POSTSCRIPT = 6;
100
125
  const NAME_ID_TYPOGRAPHIC_FAMILY = 16;
@@ -103,9 +128,10 @@ const PLATFORM_MACINTOSH = 1;
103
128
  const PLATFORM_WINDOWS = 3;
104
129
  const WINDOWS_ENCODING_UNICODE_BMP = 1;
105
130
  const MACINTOSH_ENCODING_ROMAN = 0;
131
+ const BITS_PER_BYTE = 8;
106
132
  function decodeUtf16Be(bytes, offset, length) {
107
133
  let text = "";
108
- for (let i = 0; i + 1 < length; i += 2) text += String.fromCharCode(bytes[offset + i] << 8 | bytes[offset + i + 1]);
134
+ for (let i = 0; i + 1 < length; i += 2) text += String.fromCharCode(bytes[offset + i] << BITS_PER_BYTE | bytes[offset + i + 1]);
109
135
  return text;
110
136
  }
111
137
  function decodeMacRoman(bytes, offset, length) {
@@ -113,14 +139,15 @@ function decodeMacRoman(bytes, offset, length) {
113
139
  for (let i = 0; i < length; i++) text += String.fromCharCode(bytes[offset + i]);
114
140
  return text;
115
141
  }
142
+ const PLATFORM_RANK_UNSUPPORTED = 3;
116
143
  function platformRank(record) {
117
144
  if (record.platformId === PLATFORM_WINDOWS && record.encodingId === WINDOWS_ENCODING_UNICODE_BMP) return 0;
118
145
  if (record.platformId === PLATFORM_UNICODE) return 1;
119
146
  if (record.platformId === PLATFORM_MACINTOSH && record.encodingId === MACINTOSH_ENCODING_ROMAN) return 2;
120
- return 3;
147
+ return PLATFORM_RANK_UNSUPPORTED;
121
148
  }
122
149
  function readName(bytes, records, nameId) {
123
- const matches = records.filter((record) => record.nameId === nameId && platformRank(record) < 3).sort((a, b) => platformRank(a) - platformRank(b));
150
+ const matches = records.filter((record) => record.nameId === nameId && platformRank(record) < PLATFORM_RANK_UNSUPPORTED).sort((a, b) => platformRank(a) - platformRank(b));
124
151
  for (const record of matches) {
125
152
  if (!require_sfnt.hasBytes(bytes, record.stringOffset, record.length)) continue;
126
153
  const text = record.platformId === PLATFORM_MACINTOSH ? decodeMacRoman(bytes, record.stringOffset, record.length) : decodeUtf16Be(bytes, record.stringOffset, record.length);
@@ -131,7 +158,7 @@ function parseName(font) {
131
158
  const bytes = require_sfnt.sfntTableBytes(font, "name");
132
159
  if (bytes === void 0 || !require_sfnt.hasBytes(bytes, 0, NAME_HEADER_SIZE)) return;
133
160
  const count = require_sfnt.u16(bytes, 2);
134
- const storageOffset = require_sfnt.u16(bytes, 4);
161
+ const storageOffset = require_sfnt.u16(bytes, NAME_HEADER_STORAGE_OFFSET_FIELD_OFFSET);
135
162
  if (!require_sfnt.hasBytes(bytes, NAME_HEADER_SIZE, count * NAME_RECORD_SIZE)) return;
136
163
  const records = [];
137
164
  for (let i = 0; i < count; i++) {
@@ -139,9 +166,9 @@ function parseName(font) {
139
166
  records.push({
140
167
  platformId: require_sfnt.u16(bytes, recordOffset),
141
168
  encodingId: require_sfnt.u16(bytes, recordOffset + 2),
142
- nameId: require_sfnt.u16(bytes, recordOffset + 6),
143
- length: require_sfnt.u16(bytes, recordOffset + 8),
144
- stringOffset: storageOffset + require_sfnt.u16(bytes, recordOffset + 10)
169
+ nameId: require_sfnt.u16(bytes, recordOffset + NAME_RECORD_NAME_ID_OFFSET),
170
+ length: require_sfnt.u16(bytes, recordOffset + NAME_RECORD_LENGTH_OFFSET),
171
+ stringOffset: storageOffset + require_sfnt.u16(bytes, recordOffset + NAME_RECORD_STRING_OFFSET_FIELD_OFFSET)
145
172
  });
146
173
  }
147
174
  return {
@@ -4,35 +4,53 @@ const HEAD_TABLE_SIZE = 54;
4
4
  const HEAD_MAGIC_NUMBER = 1594834165;
5
5
  const MIN_UNITS_PER_EM = 16;
6
6
  const MAX_UNITS_PER_EM = 16384;
7
+ const HEAD_CHECKSUM_ADJUSTMENT_OFFSET = 8;
8
+ const HEAD_MAGIC_NUMBER_OFFSET = 12;
9
+ const HEAD_UNITS_PER_EM_OFFSET = 18;
10
+ const HEAD_X_MIN_OFFSET = 36;
11
+ const HEAD_Y_MIN_OFFSET = 38;
12
+ const HEAD_X_MAX_OFFSET = 40;
13
+ const HEAD_Y_MAX_OFFSET = 42;
14
+ const HEAD_MAC_STYLE_OFFSET = 44;
15
+ const HEAD_INDEX_TO_LOC_FORMAT_OFFSET = 50;
7
16
  function parseHead(font) {
8
17
  const bytes = sfntTableBytes(font, "head");
9
18
  if (bytes === void 0 || !hasBytes(bytes, 0, HEAD_TABLE_SIZE)) return;
10
- if (u32(bytes, 12) !== HEAD_MAGIC_NUMBER) return;
11
- const unitsPerEm = u16(bytes, 18);
19
+ if (u32(bytes, HEAD_MAGIC_NUMBER_OFFSET) !== HEAD_MAGIC_NUMBER) return;
20
+ const unitsPerEm = u16(bytes, HEAD_UNITS_PER_EM_OFFSET);
12
21
  if (unitsPerEm < MIN_UNITS_PER_EM || unitsPerEm > MAX_UNITS_PER_EM) return;
13
- const indexToLocFormat = i16(bytes, 50);
22
+ const indexToLocFormat = i16(bytes, HEAD_INDEX_TO_LOC_FORMAT_OFFSET);
14
23
  if (indexToLocFormat !== 0 && indexToLocFormat !== 1) return;
15
24
  return {
16
25
  unitsPerEm,
17
- checkSumAdjustment: u32(bytes, 8),
18
- xMin: i16(bytes, 36),
19
- yMin: i16(bytes, 38),
20
- xMax: i16(bytes, 40),
21
- yMax: i16(bytes, 42),
26
+ checkSumAdjustment: u32(bytes, HEAD_CHECKSUM_ADJUSTMENT_OFFSET),
27
+ xMin: i16(bytes, HEAD_X_MIN_OFFSET),
28
+ yMin: i16(bytes, HEAD_Y_MIN_OFFSET),
29
+ xMax: i16(bytes, HEAD_X_MAX_OFFSET),
30
+ yMax: i16(bytes, HEAD_Y_MAX_OFFSET),
22
31
  indexToLocFormat,
23
- macStyle: u16(bytes, 44)
32
+ macStyle: u16(bytes, HEAD_MAC_STYLE_OFFSET)
24
33
  };
25
34
  }
26
35
  const MAXP_HEADER_SIZE = 6;
36
+ const MAXP_NUM_GLYPHS_OFFSET = 4;
27
37
  function parseMaxp(font) {
28
38
  const bytes = sfntTableBytes(font, "maxp");
29
39
  if (bytes === void 0 || !hasBytes(bytes, 0, MAXP_HEADER_SIZE)) return;
30
- return { numGlyphs: u16(bytes, 4) };
40
+ return { numGlyphs: u16(bytes, MAXP_NUM_GLYPHS_OFFSET) };
31
41
  }
32
42
  const OS2_VERSION_0_SIZE = 78;
33
43
  const OS2_VERSION_2_SIZE = 96;
34
44
  const OS2_VERSION_WITH_HEIGHTS = 2;
35
45
  const OS2_PANOSE_OFFSET = 32;
46
+ const OS2_FS_SELECTION_OFFSET = 62;
47
+ const OS2_S_TYPO_ASCENDER_OFFSET = 68;
48
+ const OS2_S_TYPO_DESCENDER_OFFSET = 70;
49
+ const OS2_S_TYPO_LINE_GAP_OFFSET = 72;
50
+ const OS2_US_WIN_ASCENT_OFFSET = 74;
51
+ const OS2_US_WIN_DESCENT_OFFSET = 76;
52
+ const OS2_SX_HEIGHT_OFFSET = 86;
53
+ const OS2_S_CAP_HEIGHT_OFFSET = 88;
36
54
  function parseOs2(font) {
37
55
  const bytes = sfntTableBytes(font, "OS/2");
38
56
  if (bytes === void 0 || !hasBytes(bytes, 0, OS2_VERSION_0_SIZE)) return;
@@ -40,27 +58,30 @@ function parseOs2(font) {
40
58
  const hasHeights = version >= OS2_VERSION_WITH_HEIGHTS && hasBytes(bytes, 0, OS2_VERSION_2_SIZE);
41
59
  return {
42
60
  version,
43
- fsSelection: u16(bytes, 62),
61
+ fsSelection: u16(bytes, OS2_FS_SELECTION_OFFSET),
44
62
  panose: [...bytes.subarray(OS2_PANOSE_OFFSET, 42)],
45
- sTypoAscender: i16(bytes, 68),
46
- sTypoDescender: i16(bytes, 70),
47
- sTypoLineGap: i16(bytes, 72),
48
- usWinAscent: u16(bytes, 74),
49
- usWinDescent: u16(bytes, 76),
50
- sxHeight: hasHeights ? i16(bytes, 86) : void 0,
51
- sCapHeight: hasHeights ? i16(bytes, 88) : void 0
63
+ sTypoAscender: i16(bytes, OS2_S_TYPO_ASCENDER_OFFSET),
64
+ sTypoDescender: i16(bytes, OS2_S_TYPO_DESCENDER_OFFSET),
65
+ sTypoLineGap: i16(bytes, OS2_S_TYPO_LINE_GAP_OFFSET),
66
+ usWinAscent: u16(bytes, OS2_US_WIN_ASCENT_OFFSET),
67
+ usWinDescent: u16(bytes, OS2_US_WIN_DESCENT_OFFSET),
68
+ sxHeight: hasHeights ? i16(bytes, OS2_SX_HEIGHT_OFFSET) : void 0,
69
+ sCapHeight: hasHeights ? i16(bytes, OS2_S_CAP_HEIGHT_OFFSET) : void 0
52
70
  };
53
71
  }
54
72
  const POST_HEADER_SIZE = 32;
55
73
  const FIXED_16_16_SCALE = 65536;
74
+ const POST_ITALIC_ANGLE_OFFSET = 4;
75
+ const POST_UNDERLINE_POSITION_OFFSET = 8;
76
+ const POST_UNDERLINE_THICKNESS_OFFSET = 10;
56
77
  function parsePost(font) {
57
78
  const bytes = sfntTableBytes(font, "post");
58
79
  if (bytes === void 0 || !hasBytes(bytes, 0, POST_HEADER_SIZE)) return;
59
80
  return {
60
81
  version: u32(bytes, 0),
61
- italicAngle: i32(bytes, 4) / FIXED_16_16_SCALE,
62
- underlinePosition: i16(bytes, 8),
63
- underlineThickness: i16(bytes, 10)
82
+ italicAngle: i32(bytes, POST_ITALIC_ANGLE_OFFSET) / FIXED_16_16_SCALE,
83
+ underlinePosition: i16(bytes, POST_UNDERLINE_POSITION_OFFSET),
84
+ underlineThickness: i16(bytes, POST_UNDERLINE_THICKNESS_OFFSET)
64
85
  };
65
86
  }
66
87
  const MAC_STANDARD_GLYPH_ORDER = ".notdef .null nonmarkingreturn space exclam quotedbl numbersign dollar percent ampersand quotesingle parenleft parenright asterisk plus comma hyphen period slash zero one two three four five six seven eight nine colon semicolon less equal greater question at A B C D E F G H I J K L M N O P Q R S T U V W X Y Z bracketleft backslash bracketright asciicircum underscore grave a b c d e f g h i j k l m n o p q r s t u v w x y z braceleft bar braceright asciitilde Adieresis Aring Ccedilla Eacute Ntilde Odieresis Udieresis aacute agrave acircumflex adieresis atilde aring ccedilla eacute egrave ecircumflex edieresis iacute igrave icircumflex idieresis ntilde oacute ograve ocircumflex odieresis otilde uacute ugrave ucircumflex udieresis dagger degree cent sterling section bullet paragraph germandbls registered copyright trademark acute dieresis notequal AE Oslash infinity plusminus lessequal greaterequal yen mu partialdiff summation product pi integral ordfeminine ordmasculine Omega ae oslash questiondown exclamdown logicalnot radical florin approxequal Delta guillemotleft guillemotright ellipsis nonbreakingspace Agrave Atilde Otilde OE oe endash emdash quotedblleft quotedblright quoteleft quoteright divide lozenge ydieresis Ydieresis fraction currency guilsinglleft guilsinglright fi fl daggerdbl periodcentered quotesinglbase quotedblbase perthousand Acircumflex Ecircumflex Aacute Edieresis Egrave Iacute Icircumflex Idieresis Igrave Oacute Ocircumflex apple Ograve Uacute Ucircumflex Ugrave dotlessi circumflex tilde macron breve dotaccent ring cedilla hungarumlaut ogonek caron Lslash lslash Scaron scaron Zcaron zcaron brokenbar Eth eth Yacute yacute Thorn thorn minus multiply onesuperior twosuperior threesuperior onehalf onequarter threequarters franc Gbreve gbreve Idotaccent Scedilla scedilla Cacute cacute Ccaron ccaron dcroat".split(" ");
@@ -94,6 +115,10 @@ function parsePostGlyphNames(font) {
94
115
  }
95
116
  const NAME_HEADER_SIZE = 6;
96
117
  const NAME_RECORD_SIZE = 12;
118
+ const NAME_HEADER_STORAGE_OFFSET_FIELD_OFFSET = 4;
119
+ const NAME_RECORD_NAME_ID_OFFSET = 6;
120
+ const NAME_RECORD_LENGTH_OFFSET = 8;
121
+ const NAME_RECORD_STRING_OFFSET_FIELD_OFFSET = 10;
97
122
  const NAME_ID_FAMILY = 1;
98
123
  const NAME_ID_POSTSCRIPT = 6;
99
124
  const NAME_ID_TYPOGRAPHIC_FAMILY = 16;
@@ -102,9 +127,10 @@ const PLATFORM_MACINTOSH = 1;
102
127
  const PLATFORM_WINDOWS = 3;
103
128
  const WINDOWS_ENCODING_UNICODE_BMP = 1;
104
129
  const MACINTOSH_ENCODING_ROMAN = 0;
130
+ const BITS_PER_BYTE = 8;
105
131
  function decodeUtf16Be(bytes, offset, length) {
106
132
  let text = "";
107
- for (let i = 0; i + 1 < length; i += 2) text += String.fromCharCode(bytes[offset + i] << 8 | bytes[offset + i + 1]);
133
+ for (let i = 0; i + 1 < length; i += 2) text += String.fromCharCode(bytes[offset + i] << BITS_PER_BYTE | bytes[offset + i + 1]);
108
134
  return text;
109
135
  }
110
136
  function decodeMacRoman(bytes, offset, length) {
@@ -112,14 +138,15 @@ function decodeMacRoman(bytes, offset, length) {
112
138
  for (let i = 0; i < length; i++) text += String.fromCharCode(bytes[offset + i]);
113
139
  return text;
114
140
  }
141
+ const PLATFORM_RANK_UNSUPPORTED = 3;
115
142
  function platformRank(record) {
116
143
  if (record.platformId === PLATFORM_WINDOWS && record.encodingId === WINDOWS_ENCODING_UNICODE_BMP) return 0;
117
144
  if (record.platformId === PLATFORM_UNICODE) return 1;
118
145
  if (record.platformId === PLATFORM_MACINTOSH && record.encodingId === MACINTOSH_ENCODING_ROMAN) return 2;
119
- return 3;
146
+ return PLATFORM_RANK_UNSUPPORTED;
120
147
  }
121
148
  function readName(bytes, records, nameId) {
122
- const matches = records.filter((record) => record.nameId === nameId && platformRank(record) < 3).sort((a, b) => platformRank(a) - platformRank(b));
149
+ const matches = records.filter((record) => record.nameId === nameId && platformRank(record) < PLATFORM_RANK_UNSUPPORTED).sort((a, b) => platformRank(a) - platformRank(b));
123
150
  for (const record of matches) {
124
151
  if (!hasBytes(bytes, record.stringOffset, record.length)) continue;
125
152
  const text = record.platformId === PLATFORM_MACINTOSH ? decodeMacRoman(bytes, record.stringOffset, record.length) : decodeUtf16Be(bytes, record.stringOffset, record.length);
@@ -130,7 +157,7 @@ function parseName(font) {
130
157
  const bytes = sfntTableBytes(font, "name");
131
158
  if (bytes === void 0 || !hasBytes(bytes, 0, NAME_HEADER_SIZE)) return;
132
159
  const count = u16(bytes, 2);
133
- const storageOffset = u16(bytes, 4);
160
+ const storageOffset = u16(bytes, NAME_HEADER_STORAGE_OFFSET_FIELD_OFFSET);
134
161
  if (!hasBytes(bytes, NAME_HEADER_SIZE, count * NAME_RECORD_SIZE)) return;
135
162
  const records = [];
136
163
  for (let i = 0; i < count; i++) {
@@ -138,9 +165,9 @@ function parseName(font) {
138
165
  records.push({
139
166
  platformId: u16(bytes, recordOffset),
140
167
  encodingId: u16(bytes, recordOffset + 2),
141
- nameId: u16(bytes, recordOffset + 6),
142
- length: u16(bytes, recordOffset + 8),
143
- stringOffset: storageOffset + u16(bytes, recordOffset + 10)
168
+ nameId: u16(bytes, recordOffset + NAME_RECORD_NAME_ID_OFFSET),
169
+ length: u16(bytes, recordOffset + NAME_RECORD_LENGTH_OFFSET),
170
+ stringOffset: storageOffset + u16(bytes, recordOffset + NAME_RECORD_STRING_OFFSET_FIELD_OFFSET)
144
171
  });
145
172
  }
146
173
  return {