@cantoo/fontkit 2.0.5 → 2.0.7

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 (153) hide show
  1. package/dist/browser-module.d.ts +239 -0
  2. package/dist/browser-module.mjs +4423 -1117
  3. package/dist/browser-module.mjs.map +1 -1
  4. package/dist/browser.cjs +4424 -1117
  5. package/dist/browser.cjs.map +1 -1
  6. package/dist/browser.d.ts +239 -0
  7. package/dist/fontkit.umd.d.ts +239 -0
  8. package/dist/fontkit.umd.js +22076 -0
  9. package/dist/fontkit.umd.js.map +7 -0
  10. package/dist/index.d.ts +239 -0
  11. package/dist/main.cjs +4424 -1117
  12. package/dist/main.cjs.map +1 -1
  13. package/dist/main.d.ts +239 -0
  14. package/dist/module.d.ts +239 -0
  15. package/dist/module.mjs +4423 -1117
  16. package/dist/module.mjs.map +1 -1
  17. package/package.json +22 -5
  18. package/src/CmapProcessor.js +59 -20
  19. package/src/DFont.js +114 -14
  20. package/src/TTFFont.js +259 -57
  21. package/src/TrueTypeCollection.js +54 -10
  22. package/src/WOFF2Font.js +128 -16
  23. package/src/WOFFFont.js +45 -8
  24. package/src/aat/AATFeatureMap.js +62 -18
  25. package/src/aat/AATLayoutEngine.js +33 -1
  26. package/src/aat/AATLookupTable.js +22 -4
  27. package/src/aat/AATMorxProcessor.js +189 -52
  28. package/src/aat/AATStateMachine.js +32 -0
  29. package/src/base.js +19 -0
  30. package/src/cff/CFFCharsets.js +3 -0
  31. package/src/cff/CFFDict.js +79 -9
  32. package/src/cff/CFFEncodings.js +2 -0
  33. package/src/cff/CFFFont.js +119 -23
  34. package/src/cff/CFFIndex.js +62 -5
  35. package/src/cff/CFFOperand.js +52 -17
  36. package/src/cff/CFFPointer.js +41 -2
  37. package/src/cff/CFFPrivateDict.js +14 -4
  38. package/src/cff/CFFStandardStrings.js +1 -0
  39. package/src/cff/CFFTop.js +103 -10
  40. package/src/decorators.js +32 -13
  41. package/src/encodings.js +22 -5
  42. package/src/fs.js +10 -0
  43. package/src/glyph/BBox.js +14 -0
  44. package/src/glyph/CFFGlyph.js +290 -148
  45. package/src/glyph/COLRGlyph.js +38 -3
  46. package/src/glyph/Glyph.js +68 -9
  47. package/src/glyph/GlyphVariationProcessor.js +135 -34
  48. package/src/glyph/Path.js +107 -20
  49. package/src/glyph/SBIXGlyph.js +57 -8
  50. package/src/glyph/StandardNames.js +1 -0
  51. package/src/glyph/TTFGlyph.js +176 -29
  52. package/src/glyph/TTFGlyphEncoder.js +32 -0
  53. package/src/glyph/WOFF2Glyph.js +23 -4
  54. package/src/layout/GlyphPosition.js +6 -0
  55. package/src/layout/GlyphRun.js +25 -7
  56. package/src/layout/KernProcessor.js +62 -3
  57. package/src/layout/LayoutEngine.js +86 -12
  58. package/src/layout/Script.js +27 -1
  59. package/src/layout/UnicodeLayoutEngine.js +29 -4
  60. package/src/opentype/GPOSProcessor.js +156 -45
  61. package/src/opentype/GSUBProcessor.js +92 -33
  62. package/src/opentype/GlyphInfo.js +52 -4
  63. package/src/opentype/GlyphIterator.js +51 -2
  64. package/src/opentype/OTLayoutEngine.js +66 -8
  65. package/src/opentype/OTProcessor.js +283 -70
  66. package/src/opentype/ShapingPlan.js +51 -3
  67. package/src/opentype/shapers/ArabicShaper.js +19 -0
  68. package/src/opentype/shapers/DefaultShaper.js +51 -7
  69. package/src/opentype/shapers/HangulShaper.js +85 -7
  70. package/src/opentype/shapers/HebrewShaper.js +45 -11
  71. package/src/opentype/shapers/IndicShaper.js +141 -26
  72. package/src/opentype/shapers/ThaiShaper.js +35 -4
  73. package/src/opentype/shapers/UniversalShaper.js +83 -17
  74. package/src/opentype/shapers/index.js +15 -2
  75. package/src/packages/unicode-properties/data-trie.js +1 -0
  76. package/src/packages/unicode-properties/data.js +12 -0
  77. package/src/packages/unicode-properties/dist/index.cjs +22 -9
  78. package/src/packages/unicode-properties/dist/index.cjs.map +2 -2
  79. package/src/packages/unicode-properties/dist/index.mjs +21 -9
  80. package/src/packages/unicode-properties/dist/index.mjs.map +2 -2
  81. package/src/packages/unicode-properties/index.js +65 -0
  82. package/src/packages/unicode-properties/package.json +1 -1
  83. package/src/packages/unicode-trie/builder.js +128 -7
  84. package/src/packages/unicode-trie/dist/builder.cjs +129 -16
  85. package/src/packages/unicode-trie/dist/builder.cjs.map +2 -2
  86. package/src/packages/unicode-trie/dist/builder.mjs +128 -16
  87. package/src/packages/unicode-trie/dist/builder.mjs.map +2 -2
  88. package/src/packages/unicode-trie/dist/index.cjs +22 -9
  89. package/src/packages/unicode-trie/dist/index.cjs.map +2 -2
  90. package/src/packages/unicode-trie/dist/index.mjs +21 -9
  91. package/src/packages/unicode-trie/dist/index.mjs.map +2 -2
  92. package/src/packages/unicode-trie/index.js +62 -10
  93. package/src/packages/unicode-trie/package.json +1 -1
  94. package/src/packages/unicode-trie/swap.js +13 -0
  95. package/src/subset/CFFSubset.js +112 -22
  96. package/src/subset/Subset.js +21 -1
  97. package/src/subset/TTFSubset.js +79 -36
  98. package/src/tables/BASE.js +1 -0
  99. package/src/tables/COLR.js +1 -0
  100. package/src/tables/CPAL.js +1 -0
  101. package/src/tables/DSIG.js +1 -0
  102. package/src/tables/EBDT.js +10 -3
  103. package/src/tables/EBLC.js +67 -7
  104. package/src/tables/GDEF.js +1 -0
  105. package/src/tables/GPOS.js +79 -16
  106. package/src/tables/GSUB.js +14 -3
  107. package/src/tables/HVAR.js +51 -5
  108. package/src/tables/JSTF.js +3 -2
  109. package/src/tables/LTSH.js +1 -0
  110. package/src/tables/OS2.js +1 -0
  111. package/src/tables/PCLT.js +1 -0
  112. package/src/tables/STAT.js +46 -6
  113. package/src/tables/VDMX.js +1 -0
  114. package/src/tables/VORG.js +1 -0
  115. package/src/tables/WOFF2Directory.js +56 -8
  116. package/src/tables/WOFFDirectory.js +14 -2
  117. package/src/tables/aat.js +160 -35
  118. package/src/tables/avar.js +1 -0
  119. package/src/tables/bsln.js +3 -2
  120. package/src/tables/cmap.js +26 -6
  121. package/src/tables/cvt.js +1 -0
  122. package/src/tables/directory.js +44 -16
  123. package/src/tables/feat.js +24 -2
  124. package/src/tables/fpgm.js +1 -0
  125. package/src/tables/fvar.js +32 -4
  126. package/src/tables/gasp.js +1 -0
  127. package/src/tables/glyf.js +1 -0
  128. package/src/tables/gvar.js +29 -2
  129. package/src/tables/hdmx.js +12 -1
  130. package/src/tables/head.js +1 -0
  131. package/src/tables/hhea.js +1 -0
  132. package/src/tables/hmtx.js +18 -2
  133. package/src/tables/index.js +1 -0
  134. package/src/tables/just.js +15 -4
  135. package/src/tables/kern.js +43 -6
  136. package/src/tables/loca.js +21 -8
  137. package/src/tables/maxp.js +1 -0
  138. package/src/tables/morx.js +14 -7
  139. package/src/tables/name.js +104 -23
  140. package/src/tables/opbd.js +2 -1
  141. package/src/tables/opentype.js +39 -4
  142. package/src/tables/post.js +8 -1
  143. package/src/tables/prep.js +1 -0
  144. package/src/tables/sbix.js +12 -1
  145. package/src/tables/variations.js +23 -3
  146. package/src/tables/vhea.js +1 -0
  147. package/src/tables/vmtx.js +18 -2
  148. package/src/utils.js +15 -0
  149. package/types/assets.d.ts +13 -0
  150. package/types/deps.d.ts +83 -0
  151. package/types/fontkit.d.ts +1324 -0
  152. package/types/index.d.ts +239 -0
  153. package/types/restructure.d.ts +354 -0
@@ -1,36 +1,79 @@
1
1
  import { isMark } from '../packages/unicode-properties/index.js';
2
2
  import OTProcessor from './OTProcessor';
3
3
 
4
+ /** @typedef {import('../../types/fontkit').LayoutFont} LayoutFont */
5
+ /** @typedef {import('../../types/fontkit').FeatureMap} FeatureMap */
6
+ /** @typedef {import('../../types/fontkit').FeatureInput} FeatureInput */
7
+ /** @typedef {import('../../types/fontkit').ClassDefTable} ClassDefTable */
8
+
4
9
  export default class GlyphInfo {
10
+ /**
11
+ * @param {LayoutFont} font
12
+ * @param {number} id
13
+ * @param {number[]} [codePoints]
14
+ * @param {FeatureInput | null | undefined} [features]
15
+ */
5
16
  constructor(font, id, codePoints = [], features) {
17
+ /** @type {LayoutFont} */
6
18
  this._font = font;
19
+ /** @type {number[]} */
7
20
  this.codePoints = codePoints;
8
- this.id = id;
21
+ /** @type {number} */
22
+ this._id = 0;
9
23
 
24
+ /** @type {FeatureMap} */
10
25
  this.features = {};
11
26
  if (Array.isArray(features)) {
12
27
  for (let i = 0; i < features.length; i++) {
13
28
  let feature = features[i];
14
29
  this.features[feature] = true;
15
30
  }
16
- } else if (typeof features === 'object') {
31
+ } else if (typeof features === 'object' && features !== null) {
17
32
  Object.assign(this.features, features);
18
33
  }
19
34
 
35
+ /** @type {number | null} */
20
36
  this.ligatureID = null;
37
+ /** @type {number | null} */
21
38
  this.ligatureComponent = null;
39
+ /** @type {boolean} */
22
40
  this.isLigated = false;
41
+ /** @type {number | null} */
23
42
  this.cursiveAttachment = null;
43
+ /** @type {number | null} */
24
44
  this.markAttachment = null;
45
+ /** @type {import('../../types/fontkit').IndicShaperInfo | import('../../types/fontkit').USEShaperInfo | null} */
25
46
  this.shaperInfo = null;
47
+ /** @type {boolean} */
26
48
  this.substituted = false;
49
+ /** @type {boolean} */
27
50
  this.isMultiplied = false;
51
+
52
+ /** @type {boolean} */
53
+ this.isBase = false;
54
+ /** @type {boolean} */
55
+ this.isLigature = false;
56
+ /** @type {boolean} */
57
+ this.isMark = false;
58
+ /** @type {number} */
59
+ this.markAttachmentType = 0;
60
+
61
+ // Apply GDEF / mark classification via the id setter, then clear
62
+ // `substituted` — construction is not a GSUB substitution.
63
+ this.id = id;
64
+ this.substituted = false;
28
65
  }
29
66
 
67
+ /**
68
+ * @returns {number}
69
+ */
30
70
  get id() {
31
71
  return this._id;
32
72
  }
33
73
 
74
+ /**
75
+ * @param {number} id
76
+ */
34
77
  set id(id) {
35
78
  this._id = id;
36
79
  this.substituted = true;
@@ -38,11 +81,13 @@ export default class GlyphInfo {
38
81
  let GDEF = this._font.GDEF;
39
82
  if (GDEF && GDEF.glyphClassDef) {
40
83
  // TODO: clean this up
41
- let classID = OTProcessor.prototype.getClassID(id, GDEF.glyphClassDef);
84
+ let classID = OTProcessor.prototype.getClassID(id, /** @type {ClassDefTable} */ (GDEF.glyphClassDef));
42
85
  this.isBase = classID === 1;
43
86
  this.isLigature = classID === 2;
44
87
  this.isMark = classID === 3;
45
- this.markAttachmentType = GDEF.markAttachClassDef ? OTProcessor.prototype.getClassID(id, GDEF.markAttachClassDef) : 0;
88
+ this.markAttachmentType = GDEF.markAttachClassDef
89
+ ? OTProcessor.prototype.getClassID(id, /** @type {ClassDefTable} */ (GDEF.markAttachClassDef))
90
+ : 0;
46
91
  } else {
47
92
  this.isMark = this.codePoints.length > 0 && this.codePoints.every(isMark);
48
93
  this.isBase = !this.isMark;
@@ -51,6 +96,9 @@ export default class GlyphInfo {
51
96
  }
52
97
  }
53
98
 
99
+ /**
100
+ * @returns {GlyphInfo}
101
+ */
54
102
  copy() {
55
103
  return new GlyphInfo(this._font, this.id, this.codePoints, this.features);
56
104
  }
@@ -1,21 +1,48 @@
1
+ /** @typedef {import('../../types/fontkit').GlyphInfoLike} GlyphInfoLike */
2
+ /** @typedef {import('../../types/fontkit').GlyphIteratorOptions} GlyphIteratorOptions */
3
+ /** @typedef {import('../../types/fontkit').LookupFlags} LookupFlags */
4
+ /** @typedef {import('../../types/fontkit').MarkFilteringSet} MarkFilteringSet */
5
+
1
6
  export default class GlyphIterator {
7
+ /**
8
+ * @param {GlyphInfoLike[]} glyphs
9
+ * @param {GlyphIteratorOptions} [options]
10
+ */
2
11
  constructor(glyphs, options) {
12
+ /** @type {GlyphInfoLike[]} */
3
13
  this.glyphs = glyphs;
4
14
  this.reset(options);
5
15
  }
6
16
 
17
+ /**
18
+ * @param {GlyphIteratorOptions} [options]
19
+ * @param {number} [index]
20
+ * @param {MarkFilteringSet | null} [markFilteringSet]
21
+ */
7
22
  reset(options = {}, index = 0, markFilteringSet = null) {
23
+ /** @type {GlyphIteratorOptions} */
8
24
  this.options = options;
25
+ /** @type {LookupFlags} */
9
26
  this.flags = options.flags || {};
27
+ /** @type {number} */
10
28
  this.markAttachmentType = options.markAttachmentType || 0;
29
+ /** @type {MarkFilteringSet | null} */
11
30
  this.markFilteringSet = markFilteringSet;
31
+ /** @type {number} */
12
32
  this.index = index;
13
33
  }
14
34
 
35
+ /**
36
+ * @returns {GlyphInfoLike | null}
37
+ */
15
38
  get cur() {
16
39
  return this.glyphs[this.index] || null;
17
40
  }
18
41
 
42
+ /**
43
+ * @param {GlyphInfoLike} glyph
44
+ * @returns {boolean}
45
+ */
19
46
  shouldIgnore(glyph) {
20
47
  // Mark skip hierarchy (OT chapter 2): ignoreMarks > mark filtering set > markAttachmentType.
21
48
  if (glyph.isMark) {
@@ -30,10 +57,14 @@ export default class GlyphIterator {
30
57
  }
31
58
  }
32
59
 
33
- return (this.flags.ignoreBaseGlyphs && glyph.isBase)
34
- || (this.flags.ignoreLigatures && glyph.isLigature);
60
+ return !!(this.flags.ignoreBaseGlyphs && glyph.isBase)
61
+ || !!(this.flags.ignoreLigatures && glyph.isLigature);
35
62
  }
36
63
 
64
+ /**
65
+ * @param {number} dir
66
+ * @returns {GlyphInfoLike | null}
67
+ */
37
68
  move(dir) {
38
69
  this.index += dir;
39
70
  while (0 <= this.index && this.index < this.glyphs.length && this.shouldIgnore(this.glyphs[this.index])) {
@@ -47,14 +78,24 @@ export default class GlyphIterator {
47
78
  return this.glyphs[this.index];
48
79
  }
49
80
 
81
+ /**
82
+ * @returns {GlyphInfoLike | null}
83
+ */
50
84
  next() {
51
85
  return this.move(+1);
52
86
  }
53
87
 
88
+ /**
89
+ * @returns {GlyphInfoLike | null}
90
+ */
54
91
  prev() {
55
92
  return this.move(-1);
56
93
  }
57
94
 
95
+ /**
96
+ * @param {number} [count]
97
+ * @returns {GlyphInfoLike | undefined}
98
+ */
58
99
  peek(count = 1) {
59
100
  let idx = this.index;
60
101
  let res = this.increment(count);
@@ -62,6 +103,10 @@ export default class GlyphIterator {
62
103
  return res;
63
104
  }
64
105
 
106
+ /**
107
+ * @param {number} [count]
108
+ * @returns {number}
109
+ */
65
110
  peekIndex(count = 1) {
66
111
  let idx = this.index;
67
112
  this.increment(count);
@@ -70,6 +115,10 @@ export default class GlyphIterator {
70
115
  return res;
71
116
  }
72
117
 
118
+ /**
119
+ * @param {number} [count]
120
+ * @returns {GlyphInfoLike | undefined}
121
+ */
73
122
  increment(count = 1) {
74
123
  let dir = count < 0 ? -1 : 1;
75
124
  count = Math.abs(count);
@@ -4,14 +4,35 @@ import GlyphInfo from './GlyphInfo';
4
4
  import GSUBProcessor from './GSUBProcessor';
5
5
  import GPOSProcessor from './GPOSProcessor';
6
6
 
7
+ /** @typedef {import('../../types/fontkit').LayoutFont} LayoutFont */
8
+ /** @typedef {import('../../types/fontkit').GlyphRunLike} GlyphRunLike */
9
+ /** @typedef {import('../../types/fontkit').GlyphInfoLike} GlyphInfoLike */
10
+ /** @typedef {import('../../types/fontkit').GlyphPositionLike} GlyphPositionLike */
11
+ /** @typedef {import('../../types/fontkit').FeatureMap} FeatureMap */
12
+ /** @typedef {import('../../types/fontkit').ScriptTag} ScriptTag */
13
+ /** @typedef {import('../../types/fontkit').LanguageTag} LanguageTag */
14
+ /** @typedef {import('../../types/fontkit').LayoutGlyph} LayoutGlyph */
15
+ /** @typedef {import('../../types/fontkit').ShaperLike} ShaperLike */
16
+
7
17
  export default class OTLayoutEngine {
18
+ /**
19
+ * @param {LayoutFont} font
20
+ */
8
21
  constructor(font) {
22
+ /** @type {LayoutFont} */
9
23
  this.font = font;
24
+ /** @type {GlyphInfo[] | null} */
10
25
  this.glyphInfos = null;
26
+ /** @type {ShapingPlan | null} */
11
27
  this.plan = null;
28
+ /** @type {GSUBProcessor | null} */
12
29
  this.GSUBProcessor = null;
30
+ /** @type {GPOSProcessor | null} */
13
31
  this.GPOSProcessor = null;
32
+ /** @type {boolean} */
14
33
  this.fallbackPosition = true;
34
+ /** @type {ShaperLike | null} */
35
+ this.shaper = null;
15
36
 
16
37
  if (font.GSUB) {
17
38
  this.GSUBProcessor = new GSUBProcessor(font, font.GSUB);
@@ -22,12 +43,18 @@ export default class OTLayoutEngine {
22
43
  }
23
44
  }
24
45
 
46
+ /**
47
+ * @param {GlyphRunLike} glyphRun
48
+ */
25
49
  setup(glyphRun) {
26
50
  // Map glyphs to GlyphInfo objects so data can be passed between
27
51
  // GSUB and GPOS without mutating the real (shared) Glyph objects.
28
- this.glyphInfos = glyphRun.glyphs.map(glyph => new GlyphInfo(this.font, glyph.id, [...glyph.codePoints]));
52
+ this.glyphInfos = /** @type {LayoutGlyph[]} */ (glyphRun.glyphs).map(
53
+ /** @param {LayoutGlyph} glyph */ glyph => new GlyphInfo(this.font, glyph.id, [...glyph.codePoints])
54
+ );
29
55
 
30
56
  // Select an OpenType script for GSUB/GPOS features.
57
+ /** @type {string | null} */
31
58
  let script = null;
32
59
  if (this.GPOSProcessor) {
33
60
  script = this.GPOSProcessor.selectScript(glyphRun.script, glyphRun.language, glyphRun.direction);
@@ -40,12 +67,13 @@ export default class OTLayoutEngine {
40
67
  // Choose the complex shaper from the buffer Unicode script (HB model). The OT
41
68
  // script may fall back to DFLT/latn even for Thai text; that must not select
42
69
  // DefaultShaper or Thai SARA AM / PUA preprocessing is skipped.
43
- this.shaper = Shapers.choose(glyphRun.script || script);
70
+ this.shaper = /** @type {ShaperLike} */ (Shapers.choose(glyphRun.script || script));
44
71
  this.plan = new ShapingPlan(this.font, script || glyphRun.script, glyphRun.direction);
45
72
  this.plan.bufferScript = glyphRun.script;
46
73
  this.shaper.plan(this.plan, this.glyphInfos, glyphRun.features);
47
74
 
48
75
  // Enabled features as true, then overlay user values (e.g. aalt: 2) without mutating input.
76
+ /** @type {FeatureMap} */
49
77
  let features = {};
50
78
  for (let key in this.plan.allFeatures) {
51
79
  features[key] = true;
@@ -53,38 +81,62 @@ export default class OTLayoutEngine {
53
81
  glyphRun.features = Object.assign(features, glyphRun.features);
54
82
  }
55
83
 
84
+ /**
85
+ * @param {GlyphRunLike} glyphRun
86
+ */
56
87
  substitute(glyphRun) {
57
- if (this.GSUBProcessor) {
88
+ if (this.GSUBProcessor && this.plan && this.glyphInfos) {
58
89
  this.plan.process(this.GSUBProcessor, this.glyphInfos);
59
90
 
60
91
  // Map glyph infos back to normal Glyph objects
61
- glyphRun.glyphs = this.glyphInfos.map(glyphInfo => this.font.getGlyph(glyphInfo.id, glyphInfo.codePoints));
92
+ /** @type {LayoutGlyph[]} */
93
+ let glyphs = [];
94
+ for (let glyphInfo of this.glyphInfos) {
95
+ let g = this.font.getGlyph(glyphInfo.id, glyphInfo.codePoints);
96
+ if (g) {
97
+ glyphs.push(g);
98
+ }
99
+ }
100
+ glyphRun.glyphs = glyphs;
62
101
  }
63
102
  }
64
103
 
104
+ /**
105
+ * @param {GlyphRunLike} glyphRun
106
+ * @returns {FeatureMap | Record<string, import('../../types/fontkit').OTFeature> | null | undefined | false}
107
+ */
65
108
  position(glyphRun) {
66
- if (this.shaper.zeroMarkWidths === 'BEFORE_GPOS') {
109
+ if (this.shaper && this.shaper.zeroMarkWidths === 'BEFORE_GPOS' && glyphRun.positions) {
67
110
  this.zeroMarkAdvances(glyphRun.positions);
68
111
  }
69
112
 
70
- if (this.GPOSProcessor) {
113
+ if (this.GPOSProcessor && this.plan && this.glyphInfos && glyphRun.positions) {
71
114
  this.plan.process(this.GPOSProcessor, this.glyphInfos, glyphRun.positions);
72
115
  }
73
116
 
74
- if (this.shaper.zeroMarkWidths === 'AFTER_GPOS') {
117
+ if (this.shaper && this.shaper.zeroMarkWidths === 'AFTER_GPOS' && glyphRun.positions) {
75
118
  this.zeroMarkAdvances(glyphRun.positions);
76
119
  }
77
120
 
78
121
  // Reverse the glyphs and positions if the script is right-to-left
79
122
  if (glyphRun.direction === 'rtl') {
80
123
  glyphRun.glyphs.reverse();
81
- glyphRun.positions.reverse();
124
+ if (glyphRun.positions) {
125
+ glyphRun.positions.reverse();
126
+ }
82
127
  }
83
128
 
84
129
  return this.GPOSProcessor && this.GPOSProcessor.features;
85
130
  }
86
131
 
132
+ /**
133
+ * @param {GlyphPositionLike[]} positions
134
+ */
87
135
  zeroMarkAdvances(positions) {
136
+ if (!this.glyphInfos) {
137
+ return;
138
+ }
139
+
88
140
  for (let i = 0; i < this.glyphInfos.length; i++) {
89
141
  if (this.glyphInfos[i].isMark) {
90
142
  positions[i].xAdvance = 0;
@@ -99,7 +151,13 @@ export default class OTLayoutEngine {
99
151
  this.shaper = null;
100
152
  }
101
153
 
154
+ /**
155
+ * @param {ScriptTag | string[] | null | undefined} script
156
+ * @param {LanguageTag | null | undefined} language
157
+ * @returns {string[]}
158
+ */
102
159
  getAvailableFeatures(script, language) {
160
+ /** @type {string[]} */
103
161
  let features = [];
104
162
 
105
163
  if (this.GSUBProcessor) {