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
@@ -10,13 +10,16 @@ const GLYPH_CLASS_COMPONENT = 4;
10
10
  const GDEF_HEADER_SIZE_1_0 = 12;
11
11
  const GDEF_HEADER_SIZE_1_2 = 14;
12
12
  const MARK_GLYPH_SETS_HEADER_SIZE = 4;
13
+ const GDEF_GLYPH_CLASS_DEF_OFFSET = 4;
14
+ const GDEF_MARK_ATTACH_CLASS_DEF_OFFSET = 10;
15
+ const MARK_GLYPH_SETS_ENTRY_SIZE_BYTES = 4;
13
16
  function parseGdefTable(font) {
14
17
  const bytes = require_sfnt.sfntTableBytes(font, "GDEF");
15
18
  if (bytes === void 0 || !require_sfnt.hasBytes(bytes, 0, GDEF_HEADER_SIZE_1_0) || require_sfnt.u16(bytes, 0) !== 1) return;
16
19
  const minorVersion = require_sfnt.u16(bytes, 2);
17
- const glyphClassDefOffset = require_sfnt.u16(bytes, 4);
20
+ const glyphClassDefOffset = require_sfnt.u16(bytes, GDEF_GLYPH_CLASS_DEF_OFFSET);
18
21
  const glyphClassDef = glyphClassDefOffset === 0 ? void 0 : require_ot_layout_common.parseClassDef(bytes, glyphClassDefOffset);
19
- const markAttachClassDefOffset = require_sfnt.u16(bytes, 10);
22
+ const markAttachClassDefOffset = require_sfnt.u16(bytes, GDEF_MARK_ATTACH_CLASS_DEF_OFFSET);
20
23
  const markAttachClassDef = markAttachClassDefOffset === 0 ? void 0 : require_ot_layout_common.parseClassDef(bytes, markAttachClassDefOffset);
21
24
  const markGlyphSets = [];
22
25
  if (minorVersion >= 2 && require_sfnt.hasBytes(bytes, 0, GDEF_HEADER_SIZE_1_2)) {
@@ -24,7 +27,7 @@ function parseGdefTable(font) {
24
27
  if (markGlyphSetsDefOffset !== 0 && require_sfnt.hasBytes(bytes, markGlyphSetsDefOffset, MARK_GLYPH_SETS_HEADER_SIZE) && require_sfnt.u16(bytes, markGlyphSetsDefOffset) === 1) {
25
28
  const setCount = require_sfnt.u16(bytes, markGlyphSetsDefOffset + 2);
26
29
  const coverageOffsetsOffset = markGlyphSetsDefOffset + MARK_GLYPH_SETS_HEADER_SIZE;
27
- if (require_sfnt.hasBytes(bytes, coverageOffsetsOffset, setCount * 4)) for (let i = 0; i < setCount; i++) markGlyphSets.push(require_ot_layout_common.parseCoverage(bytes, markGlyphSetsDefOffset + require_sfnt.u32(bytes, coverageOffsetsOffset + i * 4)));
30
+ if (require_sfnt.hasBytes(bytes, coverageOffsetsOffset, setCount * MARK_GLYPH_SETS_ENTRY_SIZE_BYTES)) for (let i = 0; i < setCount; i++) markGlyphSets.push(require_ot_layout_common.parseCoverage(bytes, markGlyphSetsDefOffset + require_sfnt.u32(bytes, coverageOffsetsOffset + i * MARK_GLYPH_SETS_ENTRY_SIZE_BYTES)));
28
31
  }
29
32
  }
30
33
  return {
@@ -9,13 +9,16 @@ const GLYPH_CLASS_COMPONENT = 4;
9
9
  const GDEF_HEADER_SIZE_1_0 = 12;
10
10
  const GDEF_HEADER_SIZE_1_2 = 14;
11
11
  const MARK_GLYPH_SETS_HEADER_SIZE = 4;
12
+ const GDEF_GLYPH_CLASS_DEF_OFFSET = 4;
13
+ const GDEF_MARK_ATTACH_CLASS_DEF_OFFSET = 10;
14
+ const MARK_GLYPH_SETS_ENTRY_SIZE_BYTES = 4;
12
15
  function parseGdefTable(font) {
13
16
  const bytes = sfntTableBytes(font, "GDEF");
14
17
  if (bytes === void 0 || !hasBytes(bytes, 0, GDEF_HEADER_SIZE_1_0) || u16(bytes, 0) !== 1) return;
15
18
  const minorVersion = u16(bytes, 2);
16
- const glyphClassDefOffset = u16(bytes, 4);
19
+ const glyphClassDefOffset = u16(bytes, GDEF_GLYPH_CLASS_DEF_OFFSET);
17
20
  const glyphClassDef = glyphClassDefOffset === 0 ? void 0 : parseClassDef(bytes, glyphClassDefOffset);
18
- const markAttachClassDefOffset = u16(bytes, 10);
21
+ const markAttachClassDefOffset = u16(bytes, GDEF_MARK_ATTACH_CLASS_DEF_OFFSET);
19
22
  const markAttachClassDef = markAttachClassDefOffset === 0 ? void 0 : parseClassDef(bytes, markAttachClassDefOffset);
20
23
  const markGlyphSets = [];
21
24
  if (minorVersion >= 2 && hasBytes(bytes, 0, GDEF_HEADER_SIZE_1_2)) {
@@ -23,7 +26,7 @@ function parseGdefTable(font) {
23
26
  if (markGlyphSetsDefOffset !== 0 && hasBytes(bytes, markGlyphSetsDefOffset, MARK_GLYPH_SETS_HEADER_SIZE) && u16(bytes, markGlyphSetsDefOffset) === 1) {
24
27
  const setCount = u16(bytes, markGlyphSetsDefOffset + 2);
25
28
  const coverageOffsetsOffset = markGlyphSetsDefOffset + MARK_GLYPH_SETS_HEADER_SIZE;
26
- if (hasBytes(bytes, coverageOffsetsOffset, setCount * 4)) for (let i = 0; i < setCount; i++) markGlyphSets.push(parseCoverage(bytes, markGlyphSetsDefOffset + u32(bytes, coverageOffsetsOffset + i * 4)));
29
+ if (hasBytes(bytes, coverageOffsetsOffset, setCount * MARK_GLYPH_SETS_ENTRY_SIZE_BYTES)) for (let i = 0; i < setCount; i++) markGlyphSets.push(parseCoverage(bytes, markGlyphSetsDefOffset + u32(bytes, coverageOffsetsOffset + i * MARK_GLYPH_SETS_ENTRY_SIZE_BYTES)));
27
30
  }
28
31
  }
29
32
  return {
@@ -8,6 +8,8 @@ const FLAG_REPEAT = 8;
8
8
  const FLAG_X_SAME_OR_POSITIVE = 16;
9
9
  const FLAG_Y_SAME_OR_POSITIVE = 32;
10
10
  const MAX_COMPOSITE_DEPTH = 5;
11
+ const SCALED_COMPONENT_OFFSET = 2048;
12
+ const UNSCALED_COMPONENT_OFFSET = 4096;
11
13
  function decodeSimpleContours(glyph) {
12
14
  const numberOfContours = require_sfnt.i16(glyph, 0);
13
15
  const endPtsOffset = 10;
@@ -87,7 +89,7 @@ function placeComponentContours(contours, component) {
87
89
  0,
88
90
  1
89
91
  ];
90
- const scaledOffset = (component.flags & 2048) !== 0 && (component.flags & 4096) === 0;
92
+ const scaledOffset = (component.flags & SCALED_COMPONENT_OFFSET) !== 0 && (component.flags & UNSCALED_COMPONENT_OFFSET) === 0;
91
93
  const dx = scaledOffset ? a * component.argument1 + c * component.argument2 : component.argument1;
92
94
  const dy = scaledOffset ? b * component.argument1 + d * component.argument2 : component.argument2;
93
95
  return contours.map((points) => points.map((point) => ({
@@ -7,6 +7,8 @@ const FLAG_REPEAT = 8;
7
7
  const FLAG_X_SAME_OR_POSITIVE = 16;
8
8
  const FLAG_Y_SAME_OR_POSITIVE = 32;
9
9
  const MAX_COMPOSITE_DEPTH = 5;
10
+ const SCALED_COMPONENT_OFFSET = 2048;
11
+ const UNSCALED_COMPONENT_OFFSET = 4096;
10
12
  function decodeSimpleContours(glyph) {
11
13
  const numberOfContours = i16(glyph, 0);
12
14
  const endPtsOffset = 10;
@@ -86,7 +88,7 @@ function placeComponentContours(contours, component) {
86
88
  0,
87
89
  1
88
90
  ];
89
- const scaledOffset = (component.flags & 2048) !== 0 && (component.flags & 4096) === 0;
91
+ const scaledOffset = (component.flags & SCALED_COMPONENT_OFFSET) !== 0 && (component.flags & UNSCALED_COMPONENT_OFFSET) === 0;
90
92
  const dx = scaledOffset ? a * component.argument1 + c * component.argument2 : component.argument1;
91
93
  const dy = scaledOffset ? b * component.argument1 + d * component.argument2 : component.argument2;
92
94
  return contours.map((points) => points.map((point) => ({
package/dist/glyf.cjs CHANGED
@@ -16,6 +16,9 @@ function parseLoca(font, options) {
16
16
  return offsets;
17
17
  }
18
18
  const GLYPH_HEADER_SIZE = 10;
19
+ const GLYPH_HEADER_Y_MIN_OFFSET = 4;
20
+ const GLYPH_HEADER_X_MAX_OFFSET = 6;
21
+ const GLYPH_HEADER_Y_MAX_OFFSET = 8;
19
22
  const ARG_1_AND_2_ARE_WORDS = 1;
20
23
  const ARGS_ARE_XY_VALUES = 2;
21
24
  const WE_HAVE_A_SCALE = 8;
@@ -26,8 +29,16 @@ const SCALED_COMPONENT_OFFSET = 2048;
26
29
  const UNSCALED_COMPONENT_OFFSET = 4096;
27
30
  const MAX_COMPOSITE_DEPTH = 5;
28
31
  const COMPONENT_RECORD_HEADER_SIZE = 4;
32
+ const X_AND_Y_SCALE_SIZE = 4;
33
+ const TWO_BY_TWO_SCALE10_OFFSET = 4;
34
+ const TWO_BY_TWO_Y_SCALE_OFFSET = 6;
35
+ const TWO_BY_TWO_SIZE = 8;
36
+ const WORD_ARGS_SIZE = 4;
37
+ const BYTE_ARGS_SIZE = 2;
38
+ const SIGNED_BYTE_SIGN_THRESHOLD = 128;
39
+ const SIGNED_BYTE_MODULUS = 256;
29
40
  function signedByte(value) {
30
- return value >= 128 ? value - 256 : value;
41
+ return value >= SIGNED_BYTE_SIGN_THRESHOLD ? value - SIGNED_BYTE_MODULUS : value;
31
42
  }
32
43
  function readComponents(glyph) {
33
44
  const components = [];
@@ -39,7 +50,7 @@ function readComponents(glyph) {
39
50
  offset += COMPONENT_RECORD_HEADER_SIZE;
40
51
  const argsAreWords = (flags & ARG_1_AND_2_ARE_WORDS) !== 0;
41
52
  const argsAreXyValues = (flags & ARGS_ARE_XY_VALUES) !== 0;
42
- const argsSize = argsAreWords ? 4 : 2;
53
+ const argsSize = argsAreWords ? WORD_ARGS_SIZE : BYTE_ARGS_SIZE;
43
54
  if (!require_sfnt.hasBytes(glyph, offset, argsSize)) return;
44
55
  let argument1;
45
56
  let argument2;
@@ -63,23 +74,23 @@ function readComponents(glyph) {
63
74
  ];
64
75
  offset += 2;
65
76
  } else if ((flags & WE_HAVE_AN_X_AND_Y_SCALE) !== 0) {
66
- if (!require_sfnt.hasBytes(glyph, offset, 4)) return;
77
+ if (!require_sfnt.hasBytes(glyph, offset, X_AND_Y_SCALE_SIZE)) return;
67
78
  transform = [
68
79
  require_sfnt.f2dot14(glyph, offset),
69
80
  0,
70
81
  0,
71
82
  require_sfnt.f2dot14(glyph, offset + 2)
72
83
  ];
73
- offset += 4;
84
+ offset += X_AND_Y_SCALE_SIZE;
74
85
  } else if ((flags & WE_HAVE_A_TWO_BY_TWO) !== 0) {
75
- if (!require_sfnt.hasBytes(glyph, offset, 8)) return;
86
+ if (!require_sfnt.hasBytes(glyph, offset, TWO_BY_TWO_SIZE)) return;
76
87
  transform = [
77
88
  require_sfnt.f2dot14(glyph, offset),
78
89
  require_sfnt.f2dot14(glyph, offset + 2),
79
- require_sfnt.f2dot14(glyph, offset + 4),
80
- require_sfnt.f2dot14(glyph, offset + 6)
90
+ require_sfnt.f2dot14(glyph, offset + TWO_BY_TWO_SCALE10_OFFSET),
91
+ require_sfnt.f2dot14(glyph, offset + TWO_BY_TWO_Y_SCALE_OFFSET)
81
92
  ];
82
- offset += 8;
93
+ offset += TWO_BY_TWO_SIZE;
83
94
  }
84
95
  components.push({
85
96
  flags,
@@ -134,9 +145,9 @@ function parseGlyf(font, options) {
134
145
  return {
135
146
  numberOfContours: require_sfnt.i16(glyph, 0),
136
147
  xMin: require_sfnt.i16(glyph, 2),
137
- yMin: require_sfnt.i16(glyph, 4),
138
- xMax: require_sfnt.i16(glyph, 6),
139
- yMax: require_sfnt.i16(glyph, 8)
148
+ yMin: require_sfnt.i16(glyph, GLYPH_HEADER_Y_MIN_OFFSET),
149
+ xMax: require_sfnt.i16(glyph, GLYPH_HEADER_X_MAX_OFFSET),
150
+ yMax: require_sfnt.i16(glyph, GLYPH_HEADER_Y_MAX_OFFSET)
140
151
  };
141
152
  };
142
153
  const compositeComponents = (glyphId) => {
package/dist/glyf.js CHANGED
@@ -15,6 +15,9 @@ function parseLoca(font, options) {
15
15
  return offsets;
16
16
  }
17
17
  const GLYPH_HEADER_SIZE = 10;
18
+ const GLYPH_HEADER_Y_MIN_OFFSET = 4;
19
+ const GLYPH_HEADER_X_MAX_OFFSET = 6;
20
+ const GLYPH_HEADER_Y_MAX_OFFSET = 8;
18
21
  const ARG_1_AND_2_ARE_WORDS = 1;
19
22
  const ARGS_ARE_XY_VALUES = 2;
20
23
  const WE_HAVE_A_SCALE = 8;
@@ -25,8 +28,16 @@ const SCALED_COMPONENT_OFFSET = 2048;
25
28
  const UNSCALED_COMPONENT_OFFSET = 4096;
26
29
  const MAX_COMPOSITE_DEPTH = 5;
27
30
  const COMPONENT_RECORD_HEADER_SIZE = 4;
31
+ const X_AND_Y_SCALE_SIZE = 4;
32
+ const TWO_BY_TWO_SCALE10_OFFSET = 4;
33
+ const TWO_BY_TWO_Y_SCALE_OFFSET = 6;
34
+ const TWO_BY_TWO_SIZE = 8;
35
+ const WORD_ARGS_SIZE = 4;
36
+ const BYTE_ARGS_SIZE = 2;
37
+ const SIGNED_BYTE_SIGN_THRESHOLD = 128;
38
+ const SIGNED_BYTE_MODULUS = 256;
28
39
  function signedByte(value) {
29
- return value >= 128 ? value - 256 : value;
40
+ return value >= SIGNED_BYTE_SIGN_THRESHOLD ? value - SIGNED_BYTE_MODULUS : value;
30
41
  }
31
42
  function readComponents(glyph) {
32
43
  const components = [];
@@ -38,7 +49,7 @@ function readComponents(glyph) {
38
49
  offset += COMPONENT_RECORD_HEADER_SIZE;
39
50
  const argsAreWords = (flags & ARG_1_AND_2_ARE_WORDS) !== 0;
40
51
  const argsAreXyValues = (flags & ARGS_ARE_XY_VALUES) !== 0;
41
- const argsSize = argsAreWords ? 4 : 2;
52
+ const argsSize = argsAreWords ? WORD_ARGS_SIZE : BYTE_ARGS_SIZE;
42
53
  if (!hasBytes(glyph, offset, argsSize)) return;
43
54
  let argument1;
44
55
  let argument2;
@@ -62,23 +73,23 @@ function readComponents(glyph) {
62
73
  ];
63
74
  offset += 2;
64
75
  } else if ((flags & WE_HAVE_AN_X_AND_Y_SCALE) !== 0) {
65
- if (!hasBytes(glyph, offset, 4)) return;
76
+ if (!hasBytes(glyph, offset, X_AND_Y_SCALE_SIZE)) return;
66
77
  transform = [
67
78
  f2dot14(glyph, offset),
68
79
  0,
69
80
  0,
70
81
  f2dot14(glyph, offset + 2)
71
82
  ];
72
- offset += 4;
83
+ offset += X_AND_Y_SCALE_SIZE;
73
84
  } else if ((flags & WE_HAVE_A_TWO_BY_TWO) !== 0) {
74
- if (!hasBytes(glyph, offset, 8)) return;
85
+ if (!hasBytes(glyph, offset, TWO_BY_TWO_SIZE)) return;
75
86
  transform = [
76
87
  f2dot14(glyph, offset),
77
88
  f2dot14(glyph, offset + 2),
78
- f2dot14(glyph, offset + 4),
79
- f2dot14(glyph, offset + 6)
89
+ f2dot14(glyph, offset + TWO_BY_TWO_SCALE10_OFFSET),
90
+ f2dot14(glyph, offset + TWO_BY_TWO_Y_SCALE_OFFSET)
80
91
  ];
81
- offset += 8;
92
+ offset += TWO_BY_TWO_SIZE;
82
93
  }
83
94
  components.push({
84
95
  flags,
@@ -133,9 +144,9 @@ function parseGlyf(font, options) {
133
144
  return {
134
145
  numberOfContours: i16(glyph, 0),
135
146
  xMin: i16(glyph, 2),
136
- yMin: i16(glyph, 4),
137
- xMax: i16(glyph, 6),
138
- yMax: i16(glyph, 8)
147
+ yMin: i16(glyph, GLYPH_HEADER_Y_MIN_OFFSET),
148
+ xMax: i16(glyph, GLYPH_HEADER_X_MAX_OFFSET),
149
+ yMax: i16(glyph, GLYPH_HEADER_Y_MAX_OFFSET)
139
150
  };
140
151
  };
141
152
  const compositeComponents = (glyphId) => {
@@ -3,18 +3,27 @@ const require_sfnt = require("./sfnt.cjs");
3
3
  const require_ot_layout_common = require("./ot-layout-common.cjs");
4
4
  //#region src/gpos-table.ts
5
5
  const GPOS_HEADER_SIZE = 10;
6
+ const GPOS_SCRIPT_LIST_OFFSET_FIELD = 4;
7
+ const GPOS_FEATURE_LIST_OFFSET_FIELD = 6;
8
+ const GPOS_LOOKUP_LIST_OFFSET_FIELD = 8;
6
9
  const SCRIPT_RECORD_SIZE = 6;
10
+ const SCRIPT_RECORD_OFFSET_FIELD = 4;
7
11
  const FEATURE_RECORD_SIZE = 6;
12
+ const FEATURE_RECORD_OFFSET_FIELD = 4;
8
13
  const LANG_SYS_HEADER_SIZE = 6;
14
+ const LANG_SYS_FEATURE_INDEX_COUNT_FIELD = 4;
9
15
  const FEATURE_HEADER_SIZE = 4;
10
16
  const LOOKUP_HEADER_SIZE = 6;
17
+ const LOOKUP_SUB_TABLE_COUNT_FIELD = 4;
11
18
  const EXTENSION_POS_HEADER_SIZE = 8;
19
+ const EXTENSION_POS_OFFSET_FIELD = 4;
12
20
  const LOOKUP_TYPE_PAIR_POS = 2;
13
21
  const LOOKUP_TYPE_EXTENSION_POS = 9;
14
22
  const KERN_FEATURE_TAG = "kern";
15
23
  const PREFERRED_SCRIPT_TAGS = ["latn", "DFLT"];
24
+ const TAG_LENGTH_BYTES = 4;
16
25
  function readTag(bytes, offset) {
17
- return String.fromCharCode(require_sfnt.u8(bytes, offset), require_sfnt.u8(bytes, offset + 1), require_sfnt.u8(bytes, offset + 2), require_sfnt.u8(bytes, offset + 3));
26
+ return String.fromCharCode(require_sfnt.u8(bytes, offset), require_sfnt.u8(bytes, offset + 1), require_sfnt.u8(bytes, offset + 2), require_sfnt.u8(bytes, offset + TAG_LENGTH_BYTES - 1));
18
27
  }
19
28
  function valueRecordSize(valueFormat) {
20
29
  let size = 0;
@@ -27,14 +36,17 @@ function xAdvanceOffset(valueFormat) {
27
36
  return valueRecordSize(valueFormat & 3);
28
37
  }
29
38
  const PAIR_POS_FORMAT_1_HEADER_SIZE = 10;
39
+ const PAIR_POS_FORMAT_1_VALUE_FORMAT_1_FIELD = 4;
40
+ const PAIR_POS_FORMAT_1_VALUE_FORMAT_2_FIELD = 6;
41
+ const PAIR_POS_FORMAT_1_PAIR_SET_COUNT_FIELD = 8;
30
42
  const PAIR_VALUE_RECORD_GLYPH_SIZE = 2;
31
43
  function parsePairPosFormat1(bytes, subtableOffset) {
32
44
  if (!require_sfnt.hasBytes(bytes, subtableOffset, PAIR_POS_FORMAT_1_HEADER_SIZE)) return;
33
45
  const coverage = require_ot_layout_common.parseCoverage(bytes, subtableOffset + require_sfnt.u16(bytes, subtableOffset + 2));
34
46
  if (coverage === void 0) return;
35
- const valueFormat1 = require_sfnt.u16(bytes, subtableOffset + 4);
36
- const valueFormat2 = require_sfnt.u16(bytes, subtableOffset + 6);
37
- const pairSetCount = require_sfnt.u16(bytes, subtableOffset + 8);
47
+ const valueFormat1 = require_sfnt.u16(bytes, subtableOffset + PAIR_POS_FORMAT_1_VALUE_FORMAT_1_FIELD);
48
+ const valueFormat2 = require_sfnt.u16(bytes, subtableOffset + PAIR_POS_FORMAT_1_VALUE_FORMAT_2_FIELD);
49
+ const pairSetCount = require_sfnt.u16(bytes, subtableOffset + PAIR_POS_FORMAT_1_PAIR_SET_COUNT_FIELD);
38
50
  const pairSetOffsetsOffset = subtableOffset + PAIR_POS_FORMAT_1_HEADER_SIZE;
39
51
  if (!require_sfnt.hasBytes(bytes, pairSetOffsetsOffset, pairSetCount * 2)) return;
40
52
  const recordSize = PAIR_VALUE_RECORD_GLYPH_SIZE + valueRecordSize(valueFormat1) + valueRecordSize(valueFormat2);
@@ -60,16 +72,22 @@ function parsePairPosFormat1(bytes, subtableOffset) {
60
72
  };
61
73
  }
62
74
  const PAIR_POS_FORMAT_2_HEADER_SIZE = 16;
75
+ const PAIR_POS_FORMAT_2_VALUE_FORMAT_1_FIELD = 4;
76
+ const PAIR_POS_FORMAT_2_VALUE_FORMAT_2_FIELD = 6;
77
+ const PAIR_POS_FORMAT_2_CLASS_DEF_1_FIELD = 8;
78
+ const PAIR_POS_FORMAT_2_CLASS_DEF_2_FIELD = 10;
79
+ const PAIR_POS_FORMAT_2_CLASS_1_COUNT_FIELD = 12;
80
+ const PAIR_POS_FORMAT_2_CLASS_2_COUNT_FIELD = 14;
63
81
  function parsePairPosFormat2(bytes, subtableOffset) {
64
82
  if (!require_sfnt.hasBytes(bytes, subtableOffset, PAIR_POS_FORMAT_2_HEADER_SIZE)) return;
65
83
  const coverage = require_ot_layout_common.parseCoverage(bytes, subtableOffset + require_sfnt.u16(bytes, subtableOffset + 2));
66
- const classDef1 = require_ot_layout_common.parseClassDef(bytes, subtableOffset + require_sfnt.u16(bytes, subtableOffset + 8));
67
- const classDef2 = require_ot_layout_common.parseClassDef(bytes, subtableOffset + require_sfnt.u16(bytes, subtableOffset + 10));
84
+ const classDef1 = require_ot_layout_common.parseClassDef(bytes, subtableOffset + require_sfnt.u16(bytes, subtableOffset + PAIR_POS_FORMAT_2_CLASS_DEF_1_FIELD));
85
+ const classDef2 = require_ot_layout_common.parseClassDef(bytes, subtableOffset + require_sfnt.u16(bytes, subtableOffset + PAIR_POS_FORMAT_2_CLASS_DEF_2_FIELD));
68
86
  if (coverage === void 0 || classDef1 === void 0 || classDef2 === void 0) return;
69
- const valueFormat1 = require_sfnt.u16(bytes, subtableOffset + 4);
70
- const valueFormat2 = require_sfnt.u16(bytes, subtableOffset + 6);
71
- const class1Count = require_sfnt.u16(bytes, subtableOffset + 12);
72
- const class2Count = require_sfnt.u16(bytes, subtableOffset + 14);
87
+ const valueFormat1 = require_sfnt.u16(bytes, subtableOffset + PAIR_POS_FORMAT_2_VALUE_FORMAT_1_FIELD);
88
+ const valueFormat2 = require_sfnt.u16(bytes, subtableOffset + PAIR_POS_FORMAT_2_VALUE_FORMAT_2_FIELD);
89
+ const class1Count = require_sfnt.u16(bytes, subtableOffset + PAIR_POS_FORMAT_2_CLASS_1_COUNT_FIELD);
90
+ const class2Count = require_sfnt.u16(bytes, subtableOffset + PAIR_POS_FORMAT_2_CLASS_2_COUNT_FIELD);
73
91
  const class2RecordSize = valueRecordSize(valueFormat1) + valueRecordSize(valueFormat2);
74
92
  const class1RecordSize = class2Count * class2RecordSize;
75
93
  const matrixOffset = subtableOffset + PAIR_POS_FORMAT_2_HEADER_SIZE;
@@ -89,7 +107,7 @@ function parseSubtable(bytes, lookupType, subtableOffset) {
89
107
  if (!require_sfnt.hasBytes(bytes, subtableOffset, EXTENSION_POS_HEADER_SIZE) || require_sfnt.u16(bytes, subtableOffset) !== 1) return;
90
108
  const extensionLookupType = require_sfnt.u16(bytes, subtableOffset + 2);
91
109
  if (extensionLookupType === LOOKUP_TYPE_EXTENSION_POS) return;
92
- return parseSubtable(bytes, extensionLookupType, subtableOffset + require_sfnt.u32(bytes, subtableOffset + 4));
110
+ return parseSubtable(bytes, extensionLookupType, subtableOffset + require_sfnt.u32(bytes, subtableOffset + EXTENSION_POS_OFFSET_FIELD));
93
111
  }
94
112
  if (lookupType !== LOOKUP_TYPE_PAIR_POS) return;
95
113
  if (!require_sfnt.hasBytes(bytes, subtableOffset, 2)) return;
@@ -100,7 +118,7 @@ function parseSubtable(bytes, lookupType, subtableOffset) {
100
118
  function parseLookupSubtables(bytes, lookupOffset) {
101
119
  if (!require_sfnt.hasBytes(bytes, lookupOffset, LOOKUP_HEADER_SIZE)) return [];
102
120
  const lookupType = require_sfnt.u16(bytes, lookupOffset);
103
- const subTableCount = require_sfnt.u16(bytes, lookupOffset + 4);
121
+ const subTableCount = require_sfnt.u16(bytes, lookupOffset + LOOKUP_SUB_TABLE_COUNT_FIELD);
104
122
  const offsetsOffset = lookupOffset + LOOKUP_HEADER_SIZE;
105
123
  if (!require_sfnt.hasBytes(bytes, offsetsOffset, subTableCount * 2)) return [];
106
124
  const subtables = [];
@@ -116,7 +134,7 @@ function parseDefaultLangSysFeatureIndices(bytes, scriptOffset) {
116
134
  if (defaultLangSysOffset === 0) return [];
117
135
  const langSysOffset = scriptOffset + defaultLangSysOffset;
118
136
  if (!require_sfnt.hasBytes(bytes, langSysOffset, LANG_SYS_HEADER_SIZE)) return [];
119
- const featureIndexCount = require_sfnt.u16(bytes, langSysOffset + 4);
137
+ const featureIndexCount = require_sfnt.u16(bytes, langSysOffset + LANG_SYS_FEATURE_INDEX_COUNT_FIELD);
120
138
  const indicesOffset = langSysOffset + LANG_SYS_HEADER_SIZE;
121
139
  if (!require_sfnt.hasBytes(bytes, indicesOffset, featureIndexCount * 2)) return [];
122
140
  const indices = [];
@@ -130,9 +148,9 @@ function findScriptOffset(bytes, scriptListOffset) {
130
148
  if (!require_sfnt.hasBytes(bytes, recordsOffset, scriptCount * SCRIPT_RECORD_SIZE) || scriptCount === 0) return;
131
149
  for (const wanted of PREFERRED_SCRIPT_TAGS) for (let i = 0; i < scriptCount; i++) {
132
150
  const recordOffset = recordsOffset + i * SCRIPT_RECORD_SIZE;
133
- if (readTag(bytes, recordOffset) === wanted) return scriptListOffset + require_sfnt.u16(bytes, recordOffset + 4);
151
+ if (readTag(bytes, recordOffset) === wanted) return scriptListOffset + require_sfnt.u16(bytes, recordOffset + SCRIPT_RECORD_OFFSET_FIELD);
134
152
  }
135
- return scriptListOffset + require_sfnt.u16(bytes, recordsOffset + 4);
153
+ return scriptListOffset + require_sfnt.u16(bytes, recordsOffset + SCRIPT_RECORD_OFFSET_FIELD);
136
154
  }
137
155
  function collectKernLookupIndices(bytes, featureListOffset, featureIndices) {
138
156
  if (!require_sfnt.hasBytes(bytes, featureListOffset, 2)) return [];
@@ -145,7 +163,7 @@ function collectKernLookupIndices(bytes, featureListOffset, featureIndices) {
145
163
  if (featureIndex >= featureCount) continue;
146
164
  const recordOffset = recordsOffset + featureIndex * FEATURE_RECORD_SIZE;
147
165
  if (readTag(bytes, recordOffset) !== KERN_FEATURE_TAG) continue;
148
- const featureOffset = featureListOffset + require_sfnt.u16(bytes, recordOffset + 4);
166
+ const featureOffset = featureListOffset + require_sfnt.u16(bytes, recordOffset + FEATURE_RECORD_OFFSET_FIELD);
149
167
  if (!require_sfnt.hasBytes(bytes, featureOffset, FEATURE_HEADER_SIZE)) continue;
150
168
  const lookupIndexCount = require_sfnt.u16(bytes, featureOffset + 2);
151
169
  const indicesOffset = featureOffset + FEATURE_HEADER_SIZE;
@@ -163,11 +181,11 @@ function collectKernLookupIndices(bytes, featureListOffset, featureIndices) {
163
181
  function buildGposKernLookup(font) {
164
182
  const bytes = require_sfnt.sfntTableBytes(font, "GPOS");
165
183
  if (bytes === void 0 || !require_sfnt.hasBytes(bytes, 0, GPOS_HEADER_SIZE) || require_sfnt.u16(bytes, 0) !== 1) return;
166
- const scriptOffset = findScriptOffset(bytes, require_sfnt.u16(bytes, 4));
184
+ const scriptOffset = findScriptOffset(bytes, require_sfnt.u16(bytes, GPOS_SCRIPT_LIST_OFFSET_FIELD));
167
185
  if (scriptOffset === void 0) return;
168
- const lookupIndices = collectKernLookupIndices(bytes, require_sfnt.u16(bytes, 6), parseDefaultLangSysFeatureIndices(bytes, scriptOffset));
186
+ const lookupIndices = collectKernLookupIndices(bytes, require_sfnt.u16(bytes, GPOS_FEATURE_LIST_OFFSET_FIELD), parseDefaultLangSysFeatureIndices(bytes, scriptOffset));
169
187
  if (lookupIndices.length === 0) return;
170
- const lookupListOffset = require_sfnt.u16(bytes, 8);
188
+ const lookupListOffset = require_sfnt.u16(bytes, GPOS_LOOKUP_LIST_OFFSET_FIELD);
171
189
  if (!require_sfnt.hasBytes(bytes, lookupListOffset, 2)) return;
172
190
  const lookupCount = require_sfnt.u16(bytes, lookupListOffset);
173
191
  const lookupOffsetsOffset = lookupListOffset + 2;
@@ -2,18 +2,27 @@ import { hasBytes, i16, sfntTableBytes, u16, u32, u8 } from "./sfnt.js";
2
2
  import { parseClassDef, parseCoverage } from "./ot-layout-common.js";
3
3
  //#region src/gpos-table.ts
4
4
  const GPOS_HEADER_SIZE = 10;
5
+ const GPOS_SCRIPT_LIST_OFFSET_FIELD = 4;
6
+ const GPOS_FEATURE_LIST_OFFSET_FIELD = 6;
7
+ const GPOS_LOOKUP_LIST_OFFSET_FIELD = 8;
5
8
  const SCRIPT_RECORD_SIZE = 6;
9
+ const SCRIPT_RECORD_OFFSET_FIELD = 4;
6
10
  const FEATURE_RECORD_SIZE = 6;
11
+ const FEATURE_RECORD_OFFSET_FIELD = 4;
7
12
  const LANG_SYS_HEADER_SIZE = 6;
13
+ const LANG_SYS_FEATURE_INDEX_COUNT_FIELD = 4;
8
14
  const FEATURE_HEADER_SIZE = 4;
9
15
  const LOOKUP_HEADER_SIZE = 6;
16
+ const LOOKUP_SUB_TABLE_COUNT_FIELD = 4;
10
17
  const EXTENSION_POS_HEADER_SIZE = 8;
18
+ const EXTENSION_POS_OFFSET_FIELD = 4;
11
19
  const LOOKUP_TYPE_PAIR_POS = 2;
12
20
  const LOOKUP_TYPE_EXTENSION_POS = 9;
13
21
  const KERN_FEATURE_TAG = "kern";
14
22
  const PREFERRED_SCRIPT_TAGS = ["latn", "DFLT"];
23
+ const TAG_LENGTH_BYTES = 4;
15
24
  function readTag(bytes, offset) {
16
- return String.fromCharCode(u8(bytes, offset), u8(bytes, offset + 1), u8(bytes, offset + 2), u8(bytes, offset + 3));
25
+ return String.fromCharCode(u8(bytes, offset), u8(bytes, offset + 1), u8(bytes, offset + 2), u8(bytes, offset + TAG_LENGTH_BYTES - 1));
17
26
  }
18
27
  function valueRecordSize(valueFormat) {
19
28
  let size = 0;
@@ -26,14 +35,17 @@ function xAdvanceOffset(valueFormat) {
26
35
  return valueRecordSize(valueFormat & 3);
27
36
  }
28
37
  const PAIR_POS_FORMAT_1_HEADER_SIZE = 10;
38
+ const PAIR_POS_FORMAT_1_VALUE_FORMAT_1_FIELD = 4;
39
+ const PAIR_POS_FORMAT_1_VALUE_FORMAT_2_FIELD = 6;
40
+ const PAIR_POS_FORMAT_1_PAIR_SET_COUNT_FIELD = 8;
29
41
  const PAIR_VALUE_RECORD_GLYPH_SIZE = 2;
30
42
  function parsePairPosFormat1(bytes, subtableOffset) {
31
43
  if (!hasBytes(bytes, subtableOffset, PAIR_POS_FORMAT_1_HEADER_SIZE)) return;
32
44
  const coverage = parseCoverage(bytes, subtableOffset + u16(bytes, subtableOffset + 2));
33
45
  if (coverage === void 0) return;
34
- const valueFormat1 = u16(bytes, subtableOffset + 4);
35
- const valueFormat2 = u16(bytes, subtableOffset + 6);
36
- const pairSetCount = u16(bytes, subtableOffset + 8);
46
+ const valueFormat1 = u16(bytes, subtableOffset + PAIR_POS_FORMAT_1_VALUE_FORMAT_1_FIELD);
47
+ const valueFormat2 = u16(bytes, subtableOffset + PAIR_POS_FORMAT_1_VALUE_FORMAT_2_FIELD);
48
+ const pairSetCount = u16(bytes, subtableOffset + PAIR_POS_FORMAT_1_PAIR_SET_COUNT_FIELD);
37
49
  const pairSetOffsetsOffset = subtableOffset + PAIR_POS_FORMAT_1_HEADER_SIZE;
38
50
  if (!hasBytes(bytes, pairSetOffsetsOffset, pairSetCount * 2)) return;
39
51
  const recordSize = PAIR_VALUE_RECORD_GLYPH_SIZE + valueRecordSize(valueFormat1) + valueRecordSize(valueFormat2);
@@ -59,16 +71,22 @@ function parsePairPosFormat1(bytes, subtableOffset) {
59
71
  };
60
72
  }
61
73
  const PAIR_POS_FORMAT_2_HEADER_SIZE = 16;
74
+ const PAIR_POS_FORMAT_2_VALUE_FORMAT_1_FIELD = 4;
75
+ const PAIR_POS_FORMAT_2_VALUE_FORMAT_2_FIELD = 6;
76
+ const PAIR_POS_FORMAT_2_CLASS_DEF_1_FIELD = 8;
77
+ const PAIR_POS_FORMAT_2_CLASS_DEF_2_FIELD = 10;
78
+ const PAIR_POS_FORMAT_2_CLASS_1_COUNT_FIELD = 12;
79
+ const PAIR_POS_FORMAT_2_CLASS_2_COUNT_FIELD = 14;
62
80
  function parsePairPosFormat2(bytes, subtableOffset) {
63
81
  if (!hasBytes(bytes, subtableOffset, PAIR_POS_FORMAT_2_HEADER_SIZE)) return;
64
82
  const coverage = parseCoverage(bytes, subtableOffset + u16(bytes, subtableOffset + 2));
65
- const classDef1 = parseClassDef(bytes, subtableOffset + u16(bytes, subtableOffset + 8));
66
- const classDef2 = parseClassDef(bytes, subtableOffset + u16(bytes, subtableOffset + 10));
83
+ const classDef1 = parseClassDef(bytes, subtableOffset + u16(bytes, subtableOffset + PAIR_POS_FORMAT_2_CLASS_DEF_1_FIELD));
84
+ const classDef2 = parseClassDef(bytes, subtableOffset + u16(bytes, subtableOffset + PAIR_POS_FORMAT_2_CLASS_DEF_2_FIELD));
67
85
  if (coverage === void 0 || classDef1 === void 0 || classDef2 === void 0) return;
68
- const valueFormat1 = u16(bytes, subtableOffset + 4);
69
- const valueFormat2 = u16(bytes, subtableOffset + 6);
70
- const class1Count = u16(bytes, subtableOffset + 12);
71
- const class2Count = u16(bytes, subtableOffset + 14);
86
+ const valueFormat1 = u16(bytes, subtableOffset + PAIR_POS_FORMAT_2_VALUE_FORMAT_1_FIELD);
87
+ const valueFormat2 = u16(bytes, subtableOffset + PAIR_POS_FORMAT_2_VALUE_FORMAT_2_FIELD);
88
+ const class1Count = u16(bytes, subtableOffset + PAIR_POS_FORMAT_2_CLASS_1_COUNT_FIELD);
89
+ const class2Count = u16(bytes, subtableOffset + PAIR_POS_FORMAT_2_CLASS_2_COUNT_FIELD);
72
90
  const class2RecordSize = valueRecordSize(valueFormat1) + valueRecordSize(valueFormat2);
73
91
  const class1RecordSize = class2Count * class2RecordSize;
74
92
  const matrixOffset = subtableOffset + PAIR_POS_FORMAT_2_HEADER_SIZE;
@@ -88,7 +106,7 @@ function parseSubtable(bytes, lookupType, subtableOffset) {
88
106
  if (!hasBytes(bytes, subtableOffset, EXTENSION_POS_HEADER_SIZE) || u16(bytes, subtableOffset) !== 1) return;
89
107
  const extensionLookupType = u16(bytes, subtableOffset + 2);
90
108
  if (extensionLookupType === LOOKUP_TYPE_EXTENSION_POS) return;
91
- return parseSubtable(bytes, extensionLookupType, subtableOffset + u32(bytes, subtableOffset + 4));
109
+ return parseSubtable(bytes, extensionLookupType, subtableOffset + u32(bytes, subtableOffset + EXTENSION_POS_OFFSET_FIELD));
92
110
  }
93
111
  if (lookupType !== LOOKUP_TYPE_PAIR_POS) return;
94
112
  if (!hasBytes(bytes, subtableOffset, 2)) return;
@@ -99,7 +117,7 @@ function parseSubtable(bytes, lookupType, subtableOffset) {
99
117
  function parseLookupSubtables(bytes, lookupOffset) {
100
118
  if (!hasBytes(bytes, lookupOffset, LOOKUP_HEADER_SIZE)) return [];
101
119
  const lookupType = u16(bytes, lookupOffset);
102
- const subTableCount = u16(bytes, lookupOffset + 4);
120
+ const subTableCount = u16(bytes, lookupOffset + LOOKUP_SUB_TABLE_COUNT_FIELD);
103
121
  const offsetsOffset = lookupOffset + LOOKUP_HEADER_SIZE;
104
122
  if (!hasBytes(bytes, offsetsOffset, subTableCount * 2)) return [];
105
123
  const subtables = [];
@@ -115,7 +133,7 @@ function parseDefaultLangSysFeatureIndices(bytes, scriptOffset) {
115
133
  if (defaultLangSysOffset === 0) return [];
116
134
  const langSysOffset = scriptOffset + defaultLangSysOffset;
117
135
  if (!hasBytes(bytes, langSysOffset, LANG_SYS_HEADER_SIZE)) return [];
118
- const featureIndexCount = u16(bytes, langSysOffset + 4);
136
+ const featureIndexCount = u16(bytes, langSysOffset + LANG_SYS_FEATURE_INDEX_COUNT_FIELD);
119
137
  const indicesOffset = langSysOffset + LANG_SYS_HEADER_SIZE;
120
138
  if (!hasBytes(bytes, indicesOffset, featureIndexCount * 2)) return [];
121
139
  const indices = [];
@@ -129,9 +147,9 @@ function findScriptOffset(bytes, scriptListOffset) {
129
147
  if (!hasBytes(bytes, recordsOffset, scriptCount * SCRIPT_RECORD_SIZE) || scriptCount === 0) return;
130
148
  for (const wanted of PREFERRED_SCRIPT_TAGS) for (let i = 0; i < scriptCount; i++) {
131
149
  const recordOffset = recordsOffset + i * SCRIPT_RECORD_SIZE;
132
- if (readTag(bytes, recordOffset) === wanted) return scriptListOffset + u16(bytes, recordOffset + 4);
150
+ if (readTag(bytes, recordOffset) === wanted) return scriptListOffset + u16(bytes, recordOffset + SCRIPT_RECORD_OFFSET_FIELD);
133
151
  }
134
- return scriptListOffset + u16(bytes, recordsOffset + 4);
152
+ return scriptListOffset + u16(bytes, recordsOffset + SCRIPT_RECORD_OFFSET_FIELD);
135
153
  }
136
154
  function collectKernLookupIndices(bytes, featureListOffset, featureIndices) {
137
155
  if (!hasBytes(bytes, featureListOffset, 2)) return [];
@@ -144,7 +162,7 @@ function collectKernLookupIndices(bytes, featureListOffset, featureIndices) {
144
162
  if (featureIndex >= featureCount) continue;
145
163
  const recordOffset = recordsOffset + featureIndex * FEATURE_RECORD_SIZE;
146
164
  if (readTag(bytes, recordOffset) !== KERN_FEATURE_TAG) continue;
147
- const featureOffset = featureListOffset + u16(bytes, recordOffset + 4);
165
+ const featureOffset = featureListOffset + u16(bytes, recordOffset + FEATURE_RECORD_OFFSET_FIELD);
148
166
  if (!hasBytes(bytes, featureOffset, FEATURE_HEADER_SIZE)) continue;
149
167
  const lookupIndexCount = u16(bytes, featureOffset + 2);
150
168
  const indicesOffset = featureOffset + FEATURE_HEADER_SIZE;
@@ -162,11 +180,11 @@ function collectKernLookupIndices(bytes, featureListOffset, featureIndices) {
162
180
  function buildGposKernLookup(font) {
163
181
  const bytes = sfntTableBytes(font, "GPOS");
164
182
  if (bytes === void 0 || !hasBytes(bytes, 0, GPOS_HEADER_SIZE) || u16(bytes, 0) !== 1) return;
165
- const scriptOffset = findScriptOffset(bytes, u16(bytes, 4));
183
+ const scriptOffset = findScriptOffset(bytes, u16(bytes, GPOS_SCRIPT_LIST_OFFSET_FIELD));
166
184
  if (scriptOffset === void 0) return;
167
- const lookupIndices = collectKernLookupIndices(bytes, u16(bytes, 6), parseDefaultLangSysFeatureIndices(bytes, scriptOffset));
185
+ const lookupIndices = collectKernLookupIndices(bytes, u16(bytes, GPOS_FEATURE_LIST_OFFSET_FIELD), parseDefaultLangSysFeatureIndices(bytes, scriptOffset));
168
186
  if (lookupIndices.length === 0) return;
169
- const lookupListOffset = u16(bytes, 8);
187
+ const lookupListOffset = u16(bytes, GPOS_LOOKUP_LIST_OFFSET_FIELD);
170
188
  if (!hasBytes(bytes, lookupListOffset, 2)) return;
171
189
  const lookupCount = u16(bytes, lookupListOffset);
172
190
  const lookupOffsetsOffset = lookupListOffset + 2;