@cantoo/fontkit 2.0.5 → 2.0.6

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 (140) hide show
  1. package/dist/browser-module.mjs +4423 -1117
  2. package/dist/browser-module.mjs.map +1 -1
  3. package/dist/browser.cjs +4424 -1117
  4. package/dist/browser.cjs.map +1 -1
  5. package/dist/main.cjs +4424 -1117
  6. package/dist/main.cjs.map +1 -1
  7. package/dist/module.mjs +4423 -1117
  8. package/dist/module.mjs.map +1 -1
  9. package/package.json +3 -1
  10. package/src/CmapProcessor.js +59 -20
  11. package/src/DFont.js +114 -14
  12. package/src/TTFFont.js +259 -57
  13. package/src/TrueTypeCollection.js +54 -10
  14. package/src/WOFF2Font.js +128 -16
  15. package/src/WOFFFont.js +45 -8
  16. package/src/aat/AATFeatureMap.js +62 -18
  17. package/src/aat/AATLayoutEngine.js +33 -1
  18. package/src/aat/AATLookupTable.js +22 -4
  19. package/src/aat/AATMorxProcessor.js +189 -52
  20. package/src/aat/AATStateMachine.js +32 -0
  21. package/src/base.js +19 -0
  22. package/src/cff/CFFCharsets.js +3 -0
  23. package/src/cff/CFFDict.js +79 -9
  24. package/src/cff/CFFEncodings.js +2 -0
  25. package/src/cff/CFFFont.js +119 -23
  26. package/src/cff/CFFIndex.js +62 -5
  27. package/src/cff/CFFOperand.js +52 -17
  28. package/src/cff/CFFPointer.js +41 -2
  29. package/src/cff/CFFPrivateDict.js +14 -4
  30. package/src/cff/CFFStandardStrings.js +1 -0
  31. package/src/cff/CFFTop.js +103 -10
  32. package/src/decorators.js +32 -13
  33. package/src/encodings.js +22 -5
  34. package/src/fs.js +10 -0
  35. package/src/glyph/BBox.js +14 -0
  36. package/src/glyph/CFFGlyph.js +290 -148
  37. package/src/glyph/COLRGlyph.js +38 -3
  38. package/src/glyph/Glyph.js +68 -9
  39. package/src/glyph/GlyphVariationProcessor.js +135 -34
  40. package/src/glyph/Path.js +107 -20
  41. package/src/glyph/SBIXGlyph.js +57 -8
  42. package/src/glyph/StandardNames.js +1 -0
  43. package/src/glyph/TTFGlyph.js +176 -29
  44. package/src/glyph/TTFGlyphEncoder.js +32 -0
  45. package/src/glyph/WOFF2Glyph.js +23 -4
  46. package/src/layout/GlyphPosition.js +6 -0
  47. package/src/layout/GlyphRun.js +25 -7
  48. package/src/layout/KernProcessor.js +62 -3
  49. package/src/layout/LayoutEngine.js +86 -12
  50. package/src/layout/Script.js +27 -1
  51. package/src/layout/UnicodeLayoutEngine.js +29 -4
  52. package/src/opentype/GPOSProcessor.js +156 -45
  53. package/src/opentype/GSUBProcessor.js +92 -33
  54. package/src/opentype/GlyphInfo.js +52 -4
  55. package/src/opentype/GlyphIterator.js +51 -2
  56. package/src/opentype/OTLayoutEngine.js +66 -8
  57. package/src/opentype/OTProcessor.js +283 -70
  58. package/src/opentype/ShapingPlan.js +51 -3
  59. package/src/opentype/shapers/ArabicShaper.js +19 -0
  60. package/src/opentype/shapers/DefaultShaper.js +51 -7
  61. package/src/opentype/shapers/HangulShaper.js +85 -7
  62. package/src/opentype/shapers/HebrewShaper.js +45 -11
  63. package/src/opentype/shapers/IndicShaper.js +141 -26
  64. package/src/opentype/shapers/ThaiShaper.js +35 -4
  65. package/src/opentype/shapers/UniversalShaper.js +83 -17
  66. package/src/opentype/shapers/index.js +15 -2
  67. package/src/packages/unicode-properties/data-trie.js +1 -0
  68. package/src/packages/unicode-properties/data.js +12 -0
  69. package/src/packages/unicode-properties/dist/index.cjs +22 -9
  70. package/src/packages/unicode-properties/dist/index.cjs.map +2 -2
  71. package/src/packages/unicode-properties/dist/index.mjs +21 -9
  72. package/src/packages/unicode-properties/dist/index.mjs.map +2 -2
  73. package/src/packages/unicode-properties/index.js +65 -0
  74. package/src/packages/unicode-properties/package.json +1 -1
  75. package/src/packages/unicode-trie/builder.js +128 -7
  76. package/src/packages/unicode-trie/dist/builder.cjs +129 -16
  77. package/src/packages/unicode-trie/dist/builder.cjs.map +2 -2
  78. package/src/packages/unicode-trie/dist/builder.mjs +128 -16
  79. package/src/packages/unicode-trie/dist/builder.mjs.map +2 -2
  80. package/src/packages/unicode-trie/dist/index.cjs +22 -9
  81. package/src/packages/unicode-trie/dist/index.cjs.map +2 -2
  82. package/src/packages/unicode-trie/dist/index.mjs +21 -9
  83. package/src/packages/unicode-trie/dist/index.mjs.map +2 -2
  84. package/src/packages/unicode-trie/index.js +62 -10
  85. package/src/packages/unicode-trie/package.json +1 -1
  86. package/src/packages/unicode-trie/swap.js +13 -0
  87. package/src/subset/CFFSubset.js +112 -22
  88. package/src/subset/Subset.js +21 -1
  89. package/src/subset/TTFSubset.js +79 -36
  90. package/src/tables/BASE.js +1 -0
  91. package/src/tables/COLR.js +1 -0
  92. package/src/tables/CPAL.js +1 -0
  93. package/src/tables/DSIG.js +1 -0
  94. package/src/tables/EBDT.js +10 -3
  95. package/src/tables/EBLC.js +67 -7
  96. package/src/tables/GDEF.js +1 -0
  97. package/src/tables/GPOS.js +79 -16
  98. package/src/tables/GSUB.js +14 -3
  99. package/src/tables/HVAR.js +51 -5
  100. package/src/tables/JSTF.js +3 -2
  101. package/src/tables/LTSH.js +1 -0
  102. package/src/tables/OS2.js +1 -0
  103. package/src/tables/PCLT.js +1 -0
  104. package/src/tables/STAT.js +46 -6
  105. package/src/tables/VDMX.js +1 -0
  106. package/src/tables/VORG.js +1 -0
  107. package/src/tables/WOFF2Directory.js +56 -8
  108. package/src/tables/WOFFDirectory.js +14 -2
  109. package/src/tables/aat.js +160 -35
  110. package/src/tables/avar.js +1 -0
  111. package/src/tables/bsln.js +3 -2
  112. package/src/tables/cmap.js +26 -6
  113. package/src/tables/cvt.js +1 -0
  114. package/src/tables/directory.js +44 -16
  115. package/src/tables/feat.js +24 -2
  116. package/src/tables/fpgm.js +1 -0
  117. package/src/tables/fvar.js +32 -4
  118. package/src/tables/gasp.js +1 -0
  119. package/src/tables/glyf.js +1 -0
  120. package/src/tables/gvar.js +29 -2
  121. package/src/tables/hdmx.js +12 -1
  122. package/src/tables/head.js +1 -0
  123. package/src/tables/hhea.js +1 -0
  124. package/src/tables/hmtx.js +18 -2
  125. package/src/tables/index.js +1 -0
  126. package/src/tables/just.js +15 -4
  127. package/src/tables/kern.js +43 -6
  128. package/src/tables/loca.js +21 -8
  129. package/src/tables/maxp.js +1 -0
  130. package/src/tables/morx.js +14 -7
  131. package/src/tables/name.js +104 -23
  132. package/src/tables/opbd.js +2 -1
  133. package/src/tables/opentype.js +39 -4
  134. package/src/tables/post.js +8 -1
  135. package/src/tables/prep.js +1 -0
  136. package/src/tables/sbix.js +12 -1
  137. package/src/tables/variations.js +23 -3
  138. package/src/tables/vhea.js +1 -0
  139. package/src/tables/vmtx.js +18 -2
  140. package/src/utils.js +15 -0
@@ -1,23 +1,81 @@
1
1
  import * as r from 'restructure';
2
2
  import { getEncoding, LANGUAGES } from '../encodings';
3
3
 
4
+ /** @typedef {import('restructure').StructValue} StructValue */
5
+
6
+ /**
7
+ * @typedef {{
8
+ * platformID: number,
9
+ * encodingID: number,
10
+ * languageID: number,
11
+ * nameID: number,
12
+ * length: number,
13
+ * string: string
14
+ * }} NameRecordValue
15
+ */
16
+
17
+ /**
18
+ * @typedef {Record<string, string | unknown>} LangStringMap
19
+ */
20
+
21
+ /**
22
+ * @typedef {{
23
+ * fontFeatures: Record<number, LangStringMap>,
24
+ * reservedNameID?: Record<number, LangStringMap>,
25
+ * [key: string]: LangStringMap | Record<number, LangStringMap> | undefined
26
+ * }} NameRecordsMap
27
+ */
28
+
29
+ /**
30
+ * @typedef {StructValue & {
31
+ * version: number,
32
+ * count: number,
33
+ * stringOffset: number,
34
+ * records: NameRecordValue[] | NameRecordsMap,
35
+ * langTags?: Array<{ tag: string }>
36
+ * }} NameTableValue
37
+ */
38
+
4
39
  let NameRecord = new r.Struct({
5
40
  platformID: r.uint16,
6
41
  encodingID: r.uint16,
7
42
  languageID: r.uint16,
8
43
  nameID: r.uint16,
9
44
  length: r.uint16,
10
- string: new r.Pointer(r.uint16,
11
- new r.String('length', t => getEncoding(t.platformID, t.encodingID, t.languageID)),
12
- { type: 'parent', relativeTo: ctx => ctx.parent.stringOffset, allowNull: false }
45
+ string: new r.Pointer(
46
+ r.uint16,
47
+ new r.String(
48
+ 'length',
49
+ /** @param {StructValue} t @returns {string} */
50
+ t => getEncoding(
51
+ /** @type {number} */ (t.platformID),
52
+ /** @type {number} */ (t.encodingID),
53
+ /** @type {number} */ (t.languageID)
54
+ ) || 'utf16be'
55
+ ),
56
+ {
57
+ type: 'parent',
58
+ /** @param {StructValue} ctx @returns {number} */
59
+ relativeTo: ctx => /** @type {number} */ (/** @type {StructValue} */ (ctx.parent).stringOffset),
60
+ allowNull: false
61
+ }
13
62
  )
14
63
  });
15
64
 
16
65
  let LangTagRecord = new r.Struct({
17
66
  length: r.uint16,
18
- tag: new r.Pointer(r.uint16, new r.String('length', 'utf16be'), { type: 'parent', relativeTo: ctx => ctx.stringOffset })
67
+ tag: new r.Pointer(
68
+ r.uint16,
69
+ new r.String('length', 'utf16be'),
70
+ {
71
+ type: 'parent',
72
+ /** @param {StructValue} ctx @returns {number} */
73
+ relativeTo: ctx => /** @type {number} */ (ctx.stringOffset)
74
+ }
75
+ )
19
76
  });
20
77
 
78
+ /** @type {import('restructure').VersionedStruct} */
21
79
  var NameTable = new r.VersionedStruct(r.uint16, {
22
80
  0: {
23
81
  count: r.uint16,
@@ -64,6 +122,12 @@ const NAMES = [
64
122
  'variationsPostScriptNamePrefix'
65
123
  ];
66
124
 
125
+ /**
126
+ * @param {NameRecordValue[]} out
127
+ * @param {number} nameID
128
+ * @param {unknown} string
129
+ * @returns {void}
130
+ */
67
131
  function pushEnRecord(out, nameID, string) {
68
132
  if (typeof string !== 'string') return;
69
133
 
@@ -78,13 +142,17 @@ function pushEnRecord(out, nameID, string) {
78
142
  }
79
143
 
80
144
  NameTable.process = function (_stream) {
145
+ let self = /** @type {NameTableValue} */ (this);
146
+ /** @type {NameRecordsMap} */
81
147
  let records = { fontFeatures: {} };
82
148
 
83
- for (let record of this.records) {
84
- let language = LANGUAGES[record.platformID][record.languageID];
149
+ for (let record of /** @type {NameRecordValue[]} */ (self.records)) {
150
+ let platformMap = LANGUAGES[record.platformID] || {};
151
+ /** @type {string | undefined} */
152
+ let language = platformMap[record.languageID];
85
153
 
86
- if (language == null && this.langTags != null && record.languageID >= 0x8000) {
87
- language = this.langTags[record.languageID - 0x8000].tag;
154
+ if (language == null && self.langTags != null && record.languageID >= 0x8000) {
155
+ language = self.langTags[record.languageID - 0x8000].tag;
88
156
  }
89
157
 
90
158
  if (language == null) {
@@ -109,49 +177,62 @@ NameTable.process = function (_stream) {
109
177
  }
110
178
  }
111
179
 
112
- this.records = records;
180
+ self.records = records;
113
181
  };
114
182
 
115
183
  NameTable.preEncode = function () {
116
- if (Array.isArray(this.records)) return;
117
- this.version = 0;
184
+ let self = /** @type {NameTableValue} */ (this);
185
+ if (Array.isArray(self.records)) return;
186
+ self.version = 0;
118
187
 
188
+ /** @type {NameRecordValue[]} */
119
189
  let records = [];
120
- for (let key in this.records) {
121
- let val = this.records[key];
190
+ /** @type {NameRecordsMap} */
191
+ let map = self.records;
192
+ for (let key of Object.keys(map)) {
193
+ let val = map[key];
122
194
 
123
195
  if (key === 'fontFeatures') {
124
196
  // Mirrors of IDs < 256 are encoded via named/reserved keys above.
125
- for (let id in val) {
126
- if (+id >= 256) pushEnRecord(records, +id, val[id].en);
197
+ let features = /** @type {Record<number, LangStringMap>} */ (val);
198
+ for (let id of Object.keys(features)) {
199
+ if (+id >= 256) {
200
+ let langs = features[+id];
201
+ pushEnRecord(records, +id, langs && langs.en);
202
+ }
127
203
  }
128
204
  continue;
129
205
  }
130
206
 
131
207
  if (key === 'reservedNameID') {
132
- for (let id in val) pushEnRecord(records, +id, val[id].en);
208
+ let reserved = /** @type {Record<number, LangStringMap>} */ (val);
209
+ for (let id of Object.keys(reserved)) {
210
+ let langs = reserved[+id];
211
+ pushEnRecord(records, +id, langs && langs.en);
212
+ }
133
213
  continue;
134
214
  }
135
215
 
136
216
  let nameID = NAMES.indexOf(key);
137
217
  if (nameID < 0) continue;
138
218
 
139
- pushEnRecord(records, nameID, val.en);
219
+ let langs = /** @type {LangStringMap} */ (val);
220
+ pushEnRecord(records, nameID, langs.en);
140
221
 
141
222
  // Match historical behaviour: also write PostScript name for Mac platform.
142
- if (key === 'postscriptName' && typeof val.en === 'string') {
223
+ if (key === 'postscriptName' && typeof langs.en === 'string') {
143
224
  records.push({
144
225
  platformID: 1,
145
226
  encodingID: 0,
146
227
  languageID: 0,
147
228
  nameID,
148
- length: val.en.length,
149
- string: val.en
229
+ length: langs.en.length,
230
+ string: langs.en
150
231
  });
151
232
  }
152
233
  }
153
234
 
154
- this.records = records;
155
- this.count = records.length;
156
- this.stringOffset = NameTable.size(this, null, false);
235
+ self.records = records;
236
+ self.count = records.length;
237
+ self.stringOffset = NameTable.size(self, null, false);
157
238
  };
@@ -8,8 +8,9 @@ let OpticalBounds = new r.Struct({
8
8
  bottom: r.int16
9
9
  });
10
10
 
11
+ /** @type {import('restructure').Struct} */
11
12
  export default new r.Struct({
12
13
  version: r.fixed32,
13
14
  format: r.uint16,
14
- lookupTable: new LookupTable(OpticalBounds)
15
+ lookupTable: LookupTable(OpticalBounds)
15
16
  });
@@ -1,5 +1,8 @@
1
1
  import * as r from 'restructure';
2
2
 
3
+ /** @typedef {import('restructure').BaseType} BaseType */
4
+ /** @typedef {import('restructure').StructValue} StructValue */
5
+
3
6
  // ########################
4
7
  // Scripts and Languages #
5
8
  // ########################
@@ -27,6 +30,7 @@ let ScriptRecord = new r.Struct({
27
30
  script: new r.Pointer(r.uint16, Script, { type: 'parent' })
28
31
  });
29
32
 
33
+ /** @type {import('restructure').ArrayT} */
30
34
  export let ScriptList = new r.Array(ScriptRecord, r.uint16);
31
35
 
32
36
  // #######################
@@ -38,6 +42,7 @@ let FeatureParams = new r.Struct({
38
42
  nameID: r.uint16 // OT spec: UI Name ID or uiLabelNameId
39
43
  });
40
44
 
45
+ /** @type {import('restructure').Struct} */
41
46
  export let Feature = new r.Struct({
42
47
  featureParams: new r.Pointer(r.uint16, FeatureParams),
43
48
  lookupCount: r.uint16,
@@ -49,6 +54,7 @@ let FeatureRecord = new r.Struct({
49
54
  feature: new r.Pointer(r.uint16, Feature, { type: 'parent' })
50
55
  });
51
56
 
57
+ /** @type {import('restructure').ArrayT} */
52
58
  export let FeatureList = new r.Array(FeatureRecord, r.uint16);
53
59
 
54
60
  let LookupFlags = new r.Struct({
@@ -59,13 +65,25 @@ let LookupFlags = new r.Struct({
59
65
  ])
60
66
  });
61
67
 
68
+ /**
69
+ * @param {BaseType} SubTable
70
+ * @returns {import('restructure').LazyArray}
71
+ */
62
72
  export function LookupList(SubTable) {
63
73
  let Lookup = new r.Struct({
64
74
  lookupType: r.uint16,
65
75
  flags: LookupFlags,
66
76
  subTableCount: r.uint16,
67
77
  subTables: new r.Array(new r.Pointer(r.uint16, SubTable), 'subTableCount'),
68
- markFilteringSet: new r.Optional(r.uint16, t => t.flags.flags.useMarkFilteringSet)
78
+ markFilteringSet: new r.Optional(
79
+ r.uint16,
80
+ /** @param {StructValue} t @returns {boolean} */
81
+ (t) => {
82
+ let flags = /** @type {StructValue} */ (t.flags);
83
+ let bits = /** @type {Record<string, boolean>} */ (flags.flags);
84
+ return !!bits.useMarkFilteringSet;
85
+ }
86
+ )
69
87
  });
70
88
 
71
89
  return new r.LazyArray(new r.Pointer(r.uint16, Lookup), r.uint16);
@@ -81,6 +99,7 @@ let RangeRecord = new r.Struct({
81
99
  startCoverageIndex: r.uint16
82
100
  });
83
101
 
102
+ /** @type {import('restructure').VersionedStruct} */
84
103
  export let Coverage = new r.VersionedStruct(r.uint16, {
85
104
  1: {
86
105
  glyphCount: r.uint16,
@@ -102,6 +121,7 @@ let ClassRangeRecord = new r.Struct({
102
121
  class: r.uint16
103
122
  });
104
123
 
124
+ /** @type {import('restructure').VersionedStruct} */
105
125
  export let ClassDef = new r.VersionedStruct(r.uint16, {
106
126
  1: { // Class array
107
127
  startGlyph: r.uint16,
@@ -118,6 +138,7 @@ export let ClassDef = new r.VersionedStruct(r.uint16, {
118
138
  // Device Table #
119
139
  // ###############
120
140
 
141
+ /** @type {import('restructure').Struct} */
121
142
  export let Device = new r.Struct({
122
143
  a: r.uint16, // startSize for hinting Device, outerIndex for VariationIndex
123
144
  b: r.uint16, // endSize for Device, innerIndex for VariationIndex
@@ -136,7 +157,11 @@ let LookupRecord = new r.Struct({
136
157
  let Rule = new r.Struct({
137
158
  glyphCount: r.uint16,
138
159
  lookupCount: r.uint16,
139
- input: new r.Array(r.uint16, t => t.glyphCount - 1),
160
+ input: new r.Array(
161
+ r.uint16,
162
+ /** @param {StructValue} t @returns {number} */
163
+ t => /** @type {number} */ (t.glyphCount) - 1
164
+ ),
140
165
  lookupRecords: new r.Array(LookupRecord, 'lookupCount')
141
166
  });
142
167
 
@@ -145,12 +170,17 @@ let RuleSet = new r.Array(new r.Pointer(r.uint16, Rule), r.uint16);
145
170
  let ClassRule = new r.Struct({
146
171
  glyphCount: r.uint16,
147
172
  lookupCount: r.uint16,
148
- classes: new r.Array(r.uint16, t => t.glyphCount - 1),
173
+ classes: new r.Array(
174
+ r.uint16,
175
+ /** @param {StructValue} t @returns {number} */
176
+ t => /** @type {number} */ (t.glyphCount) - 1
177
+ ),
149
178
  lookupRecords: new r.Array(LookupRecord, 'lookupCount')
150
179
  });
151
180
 
152
181
  let ClassSet = new r.Array(new r.Pointer(r.uint16, ClassRule), r.uint16);
153
182
 
183
+ /** @type {import('restructure').VersionedStruct} */
154
184
  export let Context = new r.VersionedStruct(r.uint16, {
155
185
  1: { // Simple context
156
186
  coverage: new r.Pointer(r.uint16, Coverage),
@@ -179,7 +209,11 @@ let ChainRule = new r.Struct({
179
209
  backtrackGlyphCount: r.uint16,
180
210
  backtrack: new r.Array(r.uint16, 'backtrackGlyphCount'),
181
211
  inputGlyphCount: r.uint16,
182
- input: new r.Array(r.uint16, t => t.inputGlyphCount - 1),
212
+ input: new r.Array(
213
+ r.uint16,
214
+ /** @param {StructValue} t @returns {number} */
215
+ t => /** @type {number} */ (t.inputGlyphCount) - 1
216
+ ),
183
217
  lookaheadGlyphCount: r.uint16,
184
218
  lookahead: new r.Array(r.uint16, 'lookaheadGlyphCount'),
185
219
  lookupCount: r.uint16,
@@ -188,6 +222,7 @@ let ChainRule = new r.Struct({
188
222
 
189
223
  let ChainRuleSet = new r.Array(new r.Pointer(r.uint16, ChainRule), r.uint16);
190
224
 
225
+ /** @type {import('restructure').VersionedStruct} */
191
226
  export let ChainingContext = new r.VersionedStruct(r.uint16, {
192
227
  1: { // Simple context glyph substitution
193
228
  coverage: new r.Pointer(r.uint16, Coverage),
@@ -1,6 +1,9 @@
1
1
  import * as r from 'restructure';
2
2
 
3
+ /** @typedef {import('restructure').StructValue} StructValue */
4
+
3
5
  // PostScript information
6
+ /** @type {import('restructure').VersionedStruct} */
4
7
  export default new r.VersionedStruct(r.fixed32, {
5
8
  header: { // these fields exist at the top of all versions
6
9
  italicAngle: r.fixed32, // Italic angle in counter-clockwise degrees from the vertical.
@@ -29,6 +32,10 @@ export default new r.VersionedStruct(r.fixed32, {
29
32
  3: {}, // version 3 has no additional fields
30
33
 
31
34
  4: {
32
- map: new r.Array(r.uint32, t => t.parent.maxp.numGlyphs)
35
+ map: new r.Array(
36
+ r.uint32,
37
+ /** @param {StructValue} t @returns {number} */
38
+ t => /** @type {number} */ (/** @type {StructValue} */ (/** @type {StructValue} */ (t.parent).maxp).numGlyphs)
39
+ )
33
40
  }
34
41
  });
@@ -1,6 +1,7 @@
1
1
  import * as r from 'restructure';
2
2
 
3
3
  // Set of instructions executed whenever the point size or font transformation change
4
+ /** @type {import('restructure').Struct} */
4
5
  export default new r.Struct({
5
6
  controlValueProgram: new r.Array(r.uint8)
6
7
  });
@@ -1,14 +1,25 @@
1
1
  import * as r from 'restructure';
2
2
 
3
+ /** @typedef {import('restructure').StructValue} StructValue */
4
+
3
5
  let ImageTable = new r.Struct({
4
6
  ppem: r.uint16,
5
7
  resolution: r.uint16,
6
- imageOffsets: new r.Array(new r.Pointer(r.uint32, 'void'), t => t.parent.parent.maxp.numGlyphs + 1)
8
+ imageOffsets: new r.Array(
9
+ new r.Pointer(r.uint32, 'void'),
10
+ /** @param {StructValue} t @returns {number} */
11
+ (t) => {
12
+ let parent = /** @type {StructValue} */ (t.parent);
13
+ let grand = /** @type {StructValue} */ (parent.parent);
14
+ return /** @type {number} */ (/** @type {StructValue} */ (grand.maxp).numGlyphs) + 1;
15
+ }
16
+ )
7
17
  });
8
18
 
9
19
  // This is the Apple sbix table, used by the "Apple Color Emoji" font.
10
20
  // It includes several image tables with images for each bitmap glyph
11
21
  // of several different sizes.
22
+ /** @type {import('restructure').Struct} */
12
23
  export default new r.Struct({
13
24
  version: r.uint16,
14
25
  flags: new r.Bitfield(r.uint16, ['renderOutlines']),
@@ -1,6 +1,8 @@
1
1
  import { Feature } from './opentype';
2
2
  import * as r from 'restructure';
3
3
 
4
+ /** @typedef {import('restructure').StructValue} StructValue */
5
+
4
6
  /** *****************
5
7
  * Variation Store *
6
8
  *******************/
@@ -19,9 +21,25 @@ let VariationRegionList = new r.Struct({
19
21
  });
20
22
 
21
23
  let DeltaSet = new r.Struct({
22
- shortDeltas: new r.Array(r.int16, t => t.parent.shortDeltaCount),
23
- regionDeltas: new r.Array(r.int8, t => t.parent.regionIndexCount - t.parent.shortDeltaCount),
24
- deltas: t => t.shortDeltas.concat(t.regionDeltas)
24
+ shortDeltas: new r.Array(
25
+ r.int16,
26
+ /** @param {StructValue} t @returns {number} */
27
+ t => /** @type {number} */ (/** @type {StructValue} */ (t.parent).shortDeltaCount)
28
+ ),
29
+ regionDeltas: new r.Array(
30
+ r.int8,
31
+ /** @param {StructValue} t @returns {number} */
32
+ (t) => {
33
+ let parent = /** @type {StructValue} */ (t.parent);
34
+ return /** @type {number} */ (parent.regionIndexCount)
35
+ - /** @type {number} */ (parent.shortDeltaCount);
36
+ }
37
+ ),
38
+ /**
39
+ * @param {StructValue} t
40
+ * @returns {number[]}
41
+ */
42
+ deltas: t => /** @type {number[]} */ (t.shortDeltas).concat(/** @type {number[]} */ (t.regionDeltas))
25
43
  });
26
44
 
27
45
  let ItemVariationData = new r.Struct({
@@ -32,6 +50,7 @@ let ItemVariationData = new r.Struct({
32
50
  deltaSets: new r.Array(DeltaSet, 'itemCount')
33
51
  });
34
52
 
53
+ /** @type {import('restructure').Struct} */
35
54
  export let ItemVariationStore = new r.Struct({
36
55
  format: r.uint16,
37
56
  variationRegionList: new r.Pointer(r.uint32, VariationRegionList),
@@ -72,6 +91,7 @@ let FeatureVariationRecord = new r.Struct({
72
91
  featureTableSubstitution: new r.Pointer(r.uint32, FeatureTableSubstitution, { type: 'parent' })
73
92
  });
74
93
 
94
+ /** @type {import('restructure').Struct} */
75
95
  export let FeatureVariations = new r.Struct({
76
96
  majorVersion: r.uint16,
77
97
  minorVersion: r.uint16,
@@ -1,6 +1,7 @@
1
1
  import * as r from 'restructure';
2
2
 
3
3
  // Vertical Header Table
4
+ /** @type {import('restructure').Struct} */
4
5
  export default new r.Struct({
5
6
  version: r.fixed32, // Version number of the Vertical Header Table
6
7
  ascent: r.int16, // The vertical typographic ascender for this font
@@ -1,12 +1,28 @@
1
1
  import * as r from 'restructure';
2
2
 
3
+ /** @typedef {import('restructure').StructValue} StructValue */
4
+
3
5
  let VmtxEntry = new r.Struct({
4
6
  advance: r.uint16, // The advance height of the glyph
5
7
  bearing: r.int16 // The top sidebearing of the glyph
6
8
  });
7
9
 
8
10
  // Vertical Metrics Table
11
+ /** @type {import('restructure').Struct} */
9
12
  export default new r.Struct({
10
- metrics: new r.LazyArray(VmtxEntry, t => t.parent.vhea.numberOfMetrics),
11
- bearings: new r.LazyArray(r.int16, t => t.parent.maxp.numGlyphs - t.parent.vhea.numberOfMetrics)
13
+ metrics: new r.LazyArray(
14
+ VmtxEntry,
15
+ /** @param {StructValue} t @returns {number} */
16
+ t => /** @type {number} */ (/** @type {StructValue} */ (/** @type {StructValue} */ (t.parent).vhea).numberOfMetrics)
17
+ ),
18
+ bearings: new r.LazyArray(
19
+ r.int16,
20
+ /** @param {StructValue} t @returns {number} */
21
+ (t) => {
22
+ let parent = /** @type {StructValue} */ (t.parent);
23
+ let maxp = /** @type {StructValue} */ (parent.maxp);
24
+ let vhea = /** @type {StructValue} */ (parent.vhea);
25
+ return /** @type {number} */ (maxp.numGlyphs) - /** @type {number} */ (vhea.numberOfMetrics);
26
+ }
27
+ )
12
28
  });
package/src/utils.js CHANGED
@@ -1,3 +1,9 @@
1
+ /**
2
+ * @template T
3
+ * @param {T[]} arr
4
+ * @param {(item: T) => number} cmp
5
+ * @returns {number}
6
+ */
1
7
  export function binarySearch(arr, cmp) {
2
8
  let min = 0;
3
9
  let max = arr.length - 1;
@@ -17,6 +23,11 @@ export function binarySearch(arr, cmp) {
17
23
  return -1;
18
24
  }
19
25
 
26
+ /**
27
+ * @param {number} index
28
+ * @param {number} end
29
+ * @returns {number[]}
30
+ */
20
31
  export function range(index, end) {
21
32
  let range = [];
22
33
  while (index < end) {
@@ -34,6 +45,10 @@ for (let i = 0; i < CHARS.length; i++) {
34
45
  LOOKUP[CHARS.charCodeAt(i)] = i;
35
46
  }
36
47
 
48
+ /**
49
+ * @param {string} base64
50
+ * @returns {Uint8Array}
51
+ */
37
52
  export function decodeBase64(base64) {
38
53
  let bufferLength = base64.length * 0.75;
39
54