@cantoo/fontkit 2.0.4 → 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 (142) hide show
  1. package/dist/browser-module.mjs +4448 -1142
  2. package/dist/browser-module.mjs.map +1 -1
  3. package/dist/browser.cjs +4449 -1142
  4. package/dist/browser.cjs.map +1 -1
  5. package/dist/main.cjs +4449 -1142
  6. package/dist/main.cjs.map +1 -1
  7. package/dist/module.mjs +4448 -1142
  8. package/dist/module.mjs.map +1 -1
  9. package/package.json +4 -1
  10. package/src/CmapProcessor.js +60 -21
  11. package/src/DFont.js +114 -14
  12. package/src/TTFFont.js +260 -62
  13. package/src/TrueTypeCollection.js +59 -15
  14. package/src/WOFF2Font.js +128 -22
  15. package/src/WOFFFont.js +45 -8
  16. package/src/aat/AATFeatureMap.js +83 -40
  17. package/src/aat/AATLayoutEngine.js +34 -2
  18. package/src/aat/AATLookupTable.js +24 -6
  19. package/src/aat/AATMorxProcessor.js +202 -65
  20. package/src/aat/AATStateMachine.js +35 -3
  21. package/src/base.js +20 -1
  22. package/src/cff/CFFCharsets.js +3 -0
  23. package/src/cff/CFFDict.js +81 -11
  24. package/src/cff/CFFEncodings.js +2 -0
  25. package/src/cff/CFFFont.js +120 -24
  26. package/src/cff/CFFIndex.js +66 -9
  27. package/src/cff/CFFOperand.js +53 -28
  28. package/src/cff/CFFPointer.js +41 -2
  29. package/src/cff/CFFPrivateDict.js +34 -24
  30. package/src/cff/CFFStandardStrings.js +68 -67
  31. package/src/cff/CFFTop.js +161 -68
  32. package/src/decorators.js +34 -15
  33. package/src/encodings.js +133 -116
  34. package/src/fs.js +10 -0
  35. package/src/glyph/BBox.js +14 -0
  36. package/src/glyph/CFFGlyph.js +293 -152
  37. package/src/glyph/COLRGlyph.js +40 -5
  38. package/src/glyph/Glyph.js +72 -13
  39. package/src/glyph/GlyphVariationProcessor.js +158 -62
  40. package/src/glyph/Path.js +119 -32
  41. package/src/glyph/SBIXGlyph.js +57 -8
  42. package/src/glyph/StandardNames.js +1 -0
  43. package/src/glyph/TTFGlyph.js +203 -63
  44. package/src/glyph/TTFGlyphEncoder.js +58 -26
  45. package/src/glyph/WOFF2Glyph.js +25 -6
  46. package/src/layout/GlyphPosition.js +6 -0
  47. package/src/layout/GlyphRun.js +28 -10
  48. package/src/layout/KernProcessor.js +63 -4
  49. package/src/layout/LayoutEngine.js +99 -26
  50. package/src/layout/Script.js +52 -26
  51. package/src/layout/UnicodeLayoutEngine.js +34 -10
  52. package/src/opentype/GPOSProcessor.js +156 -45
  53. package/src/opentype/GSUBProcessor.js +92 -33
  54. package/src/opentype/GlyphInfo.js +53 -5
  55. package/src/opentype/GlyphIterator.js +51 -2
  56. package/src/opentype/OTLayoutEngine.js +66 -8
  57. package/src/opentype/OTProcessor.js +284 -71
  58. package/src/opentype/ShapingPlan.js +52 -5
  59. package/src/opentype/shapers/ArabicShaper.js +27 -8
  60. package/src/opentype/shapers/DefaultShaper.js +54 -10
  61. package/src/opentype/shapers/HangulShaper.js +120 -42
  62. package/src/opentype/shapers/HebrewShaper.js +50 -16
  63. package/src/opentype/shapers/IndicShaper.js +159 -44
  64. package/src/opentype/shapers/ThaiShaper.js +50 -19
  65. package/src/opentype/shapers/UniversalShaper.js +83 -17
  66. package/src/opentype/shapers/index.js +48 -35
  67. package/src/opentype/shapers/indic-data.js +2 -2
  68. package/src/packages/unicode-properties/data-trie.js +2 -1
  69. package/src/packages/unicode-properties/data.js +13 -1
  70. package/src/packages/unicode-properties/dist/index.cjs +23 -10
  71. package/src/packages/unicode-properties/dist/index.cjs.map +2 -2
  72. package/src/packages/unicode-properties/dist/index.mjs +22 -10
  73. package/src/packages/unicode-properties/dist/index.mjs.map +2 -2
  74. package/src/packages/unicode-properties/generate.js +3 -4
  75. package/src/packages/unicode-properties/index.js +95 -30
  76. package/src/packages/unicode-properties/package.json +1 -1
  77. package/src/packages/unicode-trie/builder.js +146 -29
  78. package/src/packages/unicode-trie/dist/builder.cjs +135 -25
  79. package/src/packages/unicode-trie/dist/builder.cjs.map +2 -2
  80. package/src/packages/unicode-trie/dist/builder.mjs +134 -25
  81. package/src/packages/unicode-trie/dist/builder.mjs.map +2 -2
  82. package/src/packages/unicode-trie/dist/index.cjs +22 -9
  83. package/src/packages/unicode-trie/dist/index.cjs.map +2 -2
  84. package/src/packages/unicode-trie/dist/index.mjs +21 -9
  85. package/src/packages/unicode-trie/dist/index.mjs.map +2 -2
  86. package/src/packages/unicode-trie/index.js +63 -12
  87. package/src/packages/unicode-trie/package.json +1 -1
  88. package/src/packages/unicode-trie/swap.js +15 -2
  89. package/src/subset/CFFSubset.js +112 -22
  90. package/src/subset/Subset.js +23 -3
  91. package/src/subset/TTFSubset.js +84 -41
  92. package/src/tables/BASE.js +28 -27
  93. package/src/tables/COLR.js +10 -9
  94. package/src/tables/CPAL.js +2 -1
  95. package/src/tables/DSIG.js +8 -7
  96. package/src/tables/EBDT.js +10 -4
  97. package/src/tables/EBLC.js +70 -10
  98. package/src/tables/GDEF.js +18 -17
  99. package/src/tables/GPOS.js +153 -90
  100. package/src/tables/GSUB.js +50 -39
  101. package/src/tables/HVAR.js +51 -5
  102. package/src/tables/JSTF.js +17 -16
  103. package/src/tables/LTSH.js +4 -3
  104. package/src/tables/OS2.js +50 -49
  105. package/src/tables/PCLT.js +16 -15
  106. package/src/tables/STAT.js +46 -6
  107. package/src/tables/VDMX.js +18 -17
  108. package/src/tables/VORG.js +8 -7
  109. package/src/tables/WOFF2Directory.js +57 -9
  110. package/src/tables/WOFFDirectory.js +32 -20
  111. package/src/tables/aat.js +160 -35
  112. package/src/tables/avar.js +1 -0
  113. package/src/tables/bsln.js +3 -2
  114. package/src/tables/cmap.js +83 -63
  115. package/src/tables/cvt.js +1 -0
  116. package/src/tables/directory.js +56 -28
  117. package/src/tables/feat.js +24 -2
  118. package/src/tables/fpgm.js +1 -0
  119. package/src/tables/fvar.js +32 -4
  120. package/src/tables/gasp.js +6 -5
  121. package/src/tables/glyf.js +2 -1
  122. package/src/tables/gvar.js +29 -2
  123. package/src/tables/hdmx.js +18 -7
  124. package/src/tables/head.js +17 -16
  125. package/src/tables/hhea.js +15 -14
  126. package/src/tables/hmtx.js +18 -2
  127. package/src/tables/index.js +1 -5
  128. package/src/tables/just.js +15 -4
  129. package/src/tables/kern.js +84 -47
  130. package/src/tables/loca.js +23 -10
  131. package/src/tables/maxp.js +16 -15
  132. package/src/tables/morx.js +27 -20
  133. package/src/tables/name.js +120 -39
  134. package/src/tables/opbd.js +2 -1
  135. package/src/tables/opentype.js +126 -91
  136. package/src/tables/post.js +18 -11
  137. package/src/tables/prep.js +1 -0
  138. package/src/tables/sbix.js +12 -1
  139. package/src/tables/variations.js +29 -9
  140. package/src/tables/vhea.js +15 -14
  141. package/src/tables/vmtx.js +20 -4
  142. package/src/utils.js +15 -0
@@ -1,12 +1,12 @@
1
1
  import * as r from 'restructure';
2
- import {Coverage, ClassDef, Device} from './opentype';
3
- import {ItemVariationStore} from './variations';
2
+ import { Coverage, ClassDef, Device } from './opentype';
3
+ import { ItemVariationStore } from './variations';
4
4
 
5
5
  let AttachPoint = new r.Array(r.uint16, r.uint16);
6
6
  let AttachList = new r.Struct({
7
- coverage: new r.Pointer(r.uint16, Coverage),
8
- glyphCount: r.uint16,
9
- attachPoints: new r.Array(new r.Pointer(r.uint16, AttachPoint), 'glyphCount')
7
+ coverage: new r.Pointer(r.uint16, Coverage),
8
+ glyphCount: r.uint16,
9
+ attachPoints: new r.Array(new r.Pointer(r.uint16, AttachPoint), 'glyphCount')
10
10
  });
11
11
 
12
12
  let CaretValue = new r.VersionedStruct(r.uint16, {
@@ -19,39 +19,40 @@ let CaretValue = new r.VersionedStruct(r.uint16, {
19
19
  },
20
20
 
21
21
  3: { // Design units plus Device table
22
- coordinate: r.int16,
23
- deviceTable: new r.Pointer(r.uint16, Device)
22
+ coordinate: r.int16,
23
+ deviceTable: new r.Pointer(r.uint16, Device)
24
24
  }
25
25
  });
26
26
 
27
27
  let LigGlyph = new r.Array(new r.Pointer(r.uint16, CaretValue), r.uint16);
28
28
 
29
29
  let LigCaretList = new r.Struct({
30
- coverage: new r.Pointer(r.uint16, Coverage),
31
- ligGlyphCount: r.uint16,
32
- ligGlyphs: new r.Array(new r.Pointer(r.uint16, LigGlyph), 'ligGlyphCount')
30
+ coverage: new r.Pointer(r.uint16, Coverage),
31
+ ligGlyphCount: r.uint16,
32
+ ligGlyphs: new r.Array(new r.Pointer(r.uint16, LigGlyph), 'ligGlyphCount')
33
33
  });
34
34
 
35
35
  let MarkGlyphSetsDef = new r.Struct({
36
36
  markSetTableFormat: r.uint16,
37
- markSetCount: r.uint16,
38
- coverage: new r.Array(new r.Pointer(r.uint32, Coverage), 'markSetCount')
37
+ markSetCount: r.uint16,
38
+ coverage: new r.Array(new r.Pointer(r.uint32, Coverage), 'markSetCount')
39
39
  });
40
40
 
41
+ /** @type {import('restructure').VersionedStruct} */
41
42
  export default new r.VersionedStruct(r.uint32, {
42
43
  header: {
43
- glyphClassDef: new r.Pointer(r.uint16, ClassDef),
44
- attachList: new r.Pointer(r.uint16, AttachList),
45
- ligCaretList: new r.Pointer(r.uint16, LigCaretList),
44
+ glyphClassDef: new r.Pointer(r.uint16, ClassDef),
45
+ attachList: new r.Pointer(r.uint16, AttachList),
46
+ ligCaretList: new r.Pointer(r.uint16, LigCaretList),
46
47
  markAttachClassDef: new r.Pointer(r.uint16, ClassDef)
47
48
  },
48
49
 
49
50
  0x00010000: {},
50
51
  0x00010002: {
51
- markGlyphSetsDef: new r.Pointer(r.uint16, MarkGlyphSetsDef)
52
+ markGlyphSetsDef: new r.Pointer(r.uint16, MarkGlyphSetsDef)
52
53
  },
53
54
  0x00010003: {
54
- markGlyphSetsDef: new r.Pointer(r.uint16, MarkGlyphSetsDef),
55
+ markGlyphSetsDef: new r.Pointer(r.uint16, MarkGlyphSetsDef),
55
56
  itemVariationStore: new r.Pointer(r.uint32, ItemVariationStore)
56
57
  }
57
58
  });
@@ -1,6 +1,12 @@
1
1
  import * as r from 'restructure';
2
- import {ScriptList, FeatureList, LookupList, Coverage, ClassDef, Device, Context, ChainingContext} from './opentype';
3
- import {FeatureVariations} from './variations';
2
+ import { ScriptList, FeatureList, LookupList, Coverage, ClassDef, Device, Context, ChainingContext } from './opentype';
3
+ import { FeatureVariations } from './variations';
4
+
5
+ /** @typedef {import('restructure').BaseType} BaseType */
6
+ /** @typedef {import('restructure').DecodeStream} DecodeStream */
7
+ /** @typedef {import('restructure').Struct} Struct */
8
+ /** @typedef {import('restructure').StructValue} StructValue */
9
+ /** @typedef {import('restructure').Pointer} Pointer */
4
10
 
5
11
  let ValueFormat = new r.Bitfield(r.uint16, [
6
12
  'xPlacement', 'yPlacement',
@@ -9,36 +15,67 @@ let ValueFormat = new r.Bitfield(r.uint16, [
9
15
  'xAdvDevice', 'yAdvDevice'
10
16
  ]);
11
17
 
18
+ /** @type {Record<string, BaseType>} */
12
19
  let types = {
13
20
  xPlacement: r.int16,
14
21
  yPlacement: r.int16,
15
- xAdvance: r.int16,
16
- yAdvance: r.int16,
17
- xPlaDevice: new r.Pointer(r.uint16, Device, { type: 'global', relativeTo: ctx => ctx.rel }),
18
- yPlaDevice: new r.Pointer(r.uint16, Device, { type: 'global', relativeTo: ctx => ctx.rel }),
19
- xAdvDevice: new r.Pointer(r.uint16, Device, { type: 'global', relativeTo: ctx => ctx.rel }),
20
- yAdvDevice: new r.Pointer(r.uint16, Device, { type: 'global', relativeTo: ctx => ctx.rel })
22
+ xAdvance: r.int16,
23
+ yAdvance: r.int16,
24
+ xPlaDevice: new r.Pointer(r.uint16, Device, {
25
+ type: 'global',
26
+ /** @param {StructValue} ctx @returns {number} */
27
+ relativeTo: ctx => /** @type {number} */ (ctx.rel)
28
+ }),
29
+ yPlaDevice: new r.Pointer(r.uint16, Device, {
30
+ type: 'global',
31
+ /** @param {StructValue} ctx @returns {number} */
32
+ relativeTo: ctx => /** @type {number} */ (ctx.rel)
33
+ }),
34
+ xAdvDevice: new r.Pointer(r.uint16, Device, {
35
+ type: 'global',
36
+ /** @param {StructValue} ctx @returns {number} */
37
+ relativeTo: ctx => /** @type {number} */ (ctx.rel)
38
+ }),
39
+ yAdvDevice: new r.Pointer(r.uint16, Device, {
40
+ type: 'global',
41
+ /** @param {StructValue} ctx @returns {number} */
42
+ relativeTo: ctx => /** @type {number} */ (ctx.rel)
43
+ })
21
44
  };
22
45
 
46
+ /**
47
+ * Dynamic GPOS value record whose fields depend on a ValueFormat bitfield.
48
+ * @implements {BaseType}
49
+ */
23
50
  class ValueRecord {
51
+ /**
52
+ * @param {string} [key]
53
+ */
24
54
  constructor(key = 'valueFormat') {
55
+ /** @type {string} */
25
56
  this.key = key;
26
57
  }
27
58
 
59
+ /**
60
+ * @param {StructValue | null | undefined} parent
61
+ * @returns {Struct | undefined}
62
+ */
28
63
  buildStruct(parent) {
29
64
  let struct = parent;
30
- while (!struct[this.key] && struct.parent) {
65
+ while (struct && !struct[this.key] && struct.parent) {
31
66
  struct = struct.parent;
32
67
  }
33
68
 
34
- if (!struct[this.key]) return;
69
+ if (!struct || !struct[this.key]) return;
35
70
 
71
+ /** @type {Record<string, BaseType | ((this: StructValue, parent: StructValue) => unknown)>} */
36
72
  let fields = {};
37
- fields.rel = () => struct._startOffset;
73
+ let start = struct;
74
+ fields.rel = () => start._startOffset;
38
75
 
39
- let format = struct[this.key];
40
- for (let key in format) {
41
- if (format[key]) {
76
+ let format = /** @type {Record<string, boolean>} */ (struct[this.key]);
77
+ for (let key of Object.keys(format)) {
78
+ if (format[key] && types[key]) {
42
79
  fields[key] = types[key];
43
80
  }
44
81
  }
@@ -46,21 +83,34 @@ class ValueRecord {
46
83
  return new r.Struct(fields);
47
84
  }
48
85
 
86
+ /**
87
+ * @param {unknown} val
88
+ * @param {StructValue | null | undefined} ctx
89
+ * @returns {number}
90
+ */
49
91
  size(val, ctx) {
50
- return this.buildStruct(ctx).size(val, ctx);
92
+ let s = this.buildStruct(ctx);
93
+ return s ? s.size(/** @type {StructValue} */ (val), ctx) : 0;
51
94
  }
52
95
 
96
+ /**
97
+ * @param {DecodeStream} stream
98
+ * @param {StructValue | null | undefined} parent
99
+ * @returns {StructValue | undefined}
100
+ */
53
101
  decode(stream, parent) {
54
- let res = this.buildStruct(parent).decode(stream, parent);
102
+ let s = this.buildStruct(parent);
103
+ if (!s) return;
104
+ let res = s.decode(stream, parent);
55
105
  delete res.rel;
56
106
  return res;
57
107
  }
58
108
  }
59
109
 
60
110
  let PairValueRecord = new r.Struct({
61
- secondGlyph: r.uint16,
62
- value1: new ValueRecord('valueFormat1'),
63
- value2: new ValueRecord('valueFormat2')
111
+ secondGlyph: r.uint16,
112
+ value1: new ValueRecord('valueFormat1'),
113
+ value2: new ValueRecord('valueFormat2')
64
114
  });
65
115
 
66
116
  let PairSet = new r.Array(PairValueRecord, r.uint16);
@@ -72,131 +122,144 @@ let Class2Record = new r.Struct({
72
122
 
73
123
  let Anchor = new r.VersionedStruct(r.uint16, {
74
124
  1: { // Design units only
75
- xCoordinate: r.int16,
76
- yCoordinate: r.int16
125
+ xCoordinate: r.int16,
126
+ yCoordinate: r.int16
77
127
  },
78
128
 
79
129
  2: { // Design units plus contour point
80
- xCoordinate: r.int16,
81
- yCoordinate: r.int16,
82
- anchorPoint: r.uint16
130
+ xCoordinate: r.int16,
131
+ yCoordinate: r.int16,
132
+ anchorPoint: r.uint16
83
133
  },
84
134
 
85
135
  3: { // Design units plus Device tables
86
- xCoordinate: r.int16,
87
- yCoordinate: r.int16,
88
- xDeviceTable: new r.Pointer(r.uint16, Device),
89
- yDeviceTable: new r.Pointer(r.uint16, Device)
136
+ xCoordinate: r.int16,
137
+ yCoordinate: r.int16,
138
+ xDeviceTable: new r.Pointer(r.uint16, Device),
139
+ yDeviceTable: new r.Pointer(r.uint16, Device)
90
140
  }
91
141
  });
92
142
 
93
143
  let EntryExitRecord = new r.Struct({
94
- entryAnchor: new r.Pointer(r.uint16, Anchor, {type: 'parent'}),
95
- exitAnchor: new r.Pointer(r.uint16, Anchor, {type: 'parent'})
144
+ entryAnchor: new r.Pointer(r.uint16, Anchor, { type: 'parent' }),
145
+ exitAnchor: new r.Pointer(r.uint16, Anchor, { type: 'parent' })
96
146
  });
97
147
 
98
148
  let MarkRecord = new r.Struct({
99
- class: r.uint16,
100
- markAnchor: new r.Pointer(r.uint16, Anchor, {type: 'parent'})
149
+ class: r.uint16,
150
+ markAnchor: new r.Pointer(r.uint16, Anchor, { type: 'parent' })
101
151
  });
102
152
 
103
153
  let MarkArray = new r.Array(MarkRecord, r.uint16);
104
154
 
105
- let BaseRecord = new r.Array(new r.Pointer(r.uint16, Anchor), t => t.parent.classCount);
106
- let BaseArray = new r.Array(BaseRecord, r.uint16);
107
-
108
- let ComponentRecord = new r.Array(new r.Pointer(r.uint16, Anchor), t => t.parent.parent.classCount);
109
- let LigatureAttach = new r.Array(ComponentRecord, r.uint16);
110
- let LigatureArray = new r.Array(new r.Pointer(r.uint16, LigatureAttach), r.uint16);
111
-
155
+ let BaseRecord = new r.Array(
156
+ new r.Pointer(r.uint16, Anchor),
157
+ /** @param {StructValue} t @returns {number} */
158
+ t => /** @type {number} */ (/** @type {StructValue} */ (t.parent).classCount)
159
+ );
160
+ let BaseArray = new r.Array(BaseRecord, r.uint16);
161
+
162
+ let ComponentRecord = new r.Array(
163
+ new r.Pointer(r.uint16, Anchor),
164
+ /** @param {StructValue} t @returns {number} */
165
+ t => /** @type {number} */ (
166
+ /** @type {StructValue} */ (/** @type {StructValue} */ (t.parent).parent).classCount
167
+ )
168
+ );
169
+ let LigatureAttach = new r.Array(ComponentRecord, r.uint16);
170
+ let LigatureArray = new r.Array(new r.Pointer(r.uint16, LigatureAttach), r.uint16);
171
+
172
+ /** @type {import('restructure').VersionedStruct} */
112
173
  let GPOSLookup = new r.VersionedStruct('lookupType', {
113
174
  1: new r.VersionedStruct(r.uint16, { // Single Adjustment
114
175
  1: { // Single positioning value
115
- coverage: new r.Pointer(r.uint16, Coverage),
116
- valueFormat: ValueFormat,
117
- value: new ValueRecord()
176
+ coverage: new r.Pointer(r.uint16, Coverage),
177
+ valueFormat: ValueFormat,
178
+ value: new ValueRecord()
118
179
  },
119
180
  2: {
120
- coverage: new r.Pointer(r.uint16, Coverage),
121
- valueFormat: ValueFormat,
122
- valueCount: r.uint16,
123
- values: new r.LazyArray(new ValueRecord(), 'valueCount')
181
+ coverage: new r.Pointer(r.uint16, Coverage),
182
+ valueFormat: ValueFormat,
183
+ valueCount: r.uint16,
184
+ values: new r.LazyArray(new ValueRecord(), 'valueCount')
124
185
  }
125
186
  }),
126
187
 
127
188
  2: new r.VersionedStruct(r.uint16, { // Pair Adjustment Positioning
128
189
  1: { // Adjustments for glyph pairs
129
- coverage: new r.Pointer(r.uint16, Coverage),
130
- valueFormat1: ValueFormat,
131
- valueFormat2: ValueFormat,
132
- pairSetCount: r.uint16,
133
- pairSets: new r.LazyArray(new r.Pointer(r.uint16, PairSet), 'pairSetCount')
190
+ coverage: new r.Pointer(r.uint16, Coverage),
191
+ valueFormat1: ValueFormat,
192
+ valueFormat2: ValueFormat,
193
+ pairSetCount: r.uint16,
194
+ pairSets: new r.LazyArray(new r.Pointer(r.uint16, PairSet), 'pairSetCount')
134
195
  },
135
196
 
136
197
  2: { // Class pair adjustment
137
- coverage: new r.Pointer(r.uint16, Coverage),
138
- valueFormat1: ValueFormat,
139
- valueFormat2: ValueFormat,
140
- classDef1: new r.Pointer(r.uint16, ClassDef),
141
- classDef2: new r.Pointer(r.uint16, ClassDef),
142
- class1Count: r.uint16,
143
- class2Count: r.uint16,
144
- classRecords: new r.LazyArray(new r.LazyArray(Class2Record, 'class2Count'), 'class1Count')
198
+ coverage: new r.Pointer(r.uint16, Coverage),
199
+ valueFormat1: ValueFormat,
200
+ valueFormat2: ValueFormat,
201
+ classDef1: new r.Pointer(r.uint16, ClassDef),
202
+ classDef2: new r.Pointer(r.uint16, ClassDef),
203
+ class1Count: r.uint16,
204
+ class2Count: r.uint16,
205
+ classRecords: new r.LazyArray(new r.LazyArray(Class2Record, 'class2Count'), 'class1Count')
145
206
  }
146
207
  }),
147
208
 
148
209
  3: { // Cursive Attachment Positioning
149
- format: r.uint16,
150
- coverage: new r.Pointer(r.uint16, Coverage),
151
- entryExitCount: r.uint16,
152
- entryExitRecords: new r.Array(EntryExitRecord, 'entryExitCount')
210
+ format: r.uint16,
211
+ coverage: new r.Pointer(r.uint16, Coverage),
212
+ entryExitCount: r.uint16,
213
+ entryExitRecords: new r.Array(EntryExitRecord, 'entryExitCount')
153
214
  },
154
215
 
155
216
  4: { // MarkToBase Attachment Positioning
156
- format: r.uint16,
157
- markCoverage: new r.Pointer(r.uint16, Coverage),
158
- baseCoverage: new r.Pointer(r.uint16, Coverage),
159
- classCount: r.uint16,
160
- markArray: new r.Pointer(r.uint16, MarkArray),
161
- baseArray: new r.Pointer(r.uint16, BaseArray)
217
+ format: r.uint16,
218
+ markCoverage: new r.Pointer(r.uint16, Coverage),
219
+ baseCoverage: new r.Pointer(r.uint16, Coverage),
220
+ classCount: r.uint16,
221
+ markArray: new r.Pointer(r.uint16, MarkArray),
222
+ baseArray: new r.Pointer(r.uint16, BaseArray)
162
223
  },
163
224
 
164
225
  5: { // MarkToLigature Attachment Positioning
165
- format: r.uint16,
166
- markCoverage: new r.Pointer(r.uint16, Coverage),
167
- ligatureCoverage: new r.Pointer(r.uint16, Coverage),
168
- classCount: r.uint16,
169
- markArray: new r.Pointer(r.uint16, MarkArray),
170
- ligatureArray: new r.Pointer(r.uint16, LigatureArray)
226
+ format: r.uint16,
227
+ markCoverage: new r.Pointer(r.uint16, Coverage),
228
+ ligatureCoverage: new r.Pointer(r.uint16, Coverage),
229
+ classCount: r.uint16,
230
+ markArray: new r.Pointer(r.uint16, MarkArray),
231
+ ligatureArray: new r.Pointer(r.uint16, LigatureArray)
171
232
  },
172
233
 
173
234
  6: { // MarkToMark Attachment Positioning
174
- format: r.uint16,
175
- mark1Coverage: new r.Pointer(r.uint16, Coverage),
176
- mark2Coverage: new r.Pointer(r.uint16, Coverage),
177
- classCount: r.uint16,
178
- mark1Array: new r.Pointer(r.uint16, MarkArray),
179
- mark2Array: new r.Pointer(r.uint16, BaseArray)
235
+ format: r.uint16,
236
+ mark1Coverage: new r.Pointer(r.uint16, Coverage),
237
+ mark2Coverage: new r.Pointer(r.uint16, Coverage),
238
+ classCount: r.uint16,
239
+ mark1Array: new r.Pointer(r.uint16, MarkArray),
240
+ mark2Array: new r.Pointer(r.uint16, BaseArray)
180
241
  },
181
242
 
182
- 7: Context, // Contextual positioning
183
- 8: ChainingContext, // Chaining contextual positioning
243
+ 7: Context, // Contextual positioning
244
+ 8: ChainingContext, // Chaining contextual positioning
184
245
 
185
246
  9: { // Extension Positioning
186
- posFormat: r.uint16,
187
- lookupType: r.uint16, // cannot also be 9
188
- extension: new r.Pointer(r.uint32, null)
247
+ posFormat: r.uint16,
248
+ lookupType: r.uint16, // cannot also be 9
249
+ extension: new r.Pointer(r.uint32, null)
189
250
  }
190
251
  });
191
252
 
192
253
  // Fix circular reference
193
- GPOSLookup.versions[9].extension.type = GPOSLookup;
254
+ let gposExt = /** @type {Record<string, BaseType>} */ (GPOSLookup.versions[9]);
255
+ /** @type {Pointer} */ (gposExt.extension).type = GPOSLookup;
194
256
 
257
+ /** @type {import('restructure').VersionedStruct} */
195
258
  export default new r.VersionedStruct(r.uint32, {
196
259
  header: {
197
- scriptList: new r.Pointer(r.uint16, ScriptList),
198
- featureList: new r.Pointer(r.uint16, FeatureList),
199
- lookupList: new r.Pointer(r.uint16, new LookupList(GPOSLookup))
260
+ scriptList: new r.Pointer(r.uint16, ScriptList),
261
+ featureList: new r.Pointer(r.uint16, FeatureList),
262
+ lookupList: new r.Pointer(r.uint16, LookupList(GPOSLookup))
200
263
  },
201
264
 
202
265
  0x00010000: {},
@@ -1,81 +1,92 @@
1
1
  import * as r from 'restructure';
2
- import {ScriptList, FeatureList, LookupList, Coverage, Context, ChainingContext} from './opentype';
3
- import {FeatureVariations} from './variations';
2
+ import { ScriptList, FeatureList, LookupList, Coverage, Context, ChainingContext } from './opentype';
3
+ import { FeatureVariations } from './variations';
4
+
5
+ /** @typedef {import('restructure').BaseType} BaseType */
6
+ /** @typedef {import('restructure').Pointer} Pointer */
7
+ /** @typedef {import('restructure').StructValue} StructValue */
4
8
 
5
9
  let Sequence = new r.Array(r.uint16, r.uint16);
6
10
  let AlternateSet = Sequence;
7
11
 
8
12
  let Ligature = new r.Struct({
9
- glyph: r.uint16,
10
- compCount: r.uint16,
11
- components: new r.Array(r.uint16, t => t.compCount - 1)
13
+ glyph: r.uint16,
14
+ compCount: r.uint16,
15
+ components: new r.Array(
16
+ r.uint16,
17
+ /** @param {StructValue} t @returns {number} */
18
+ t => /** @type {number} */ (t.compCount) - 1
19
+ )
12
20
  });
13
21
 
14
22
  let LigatureSet = new r.Array(new r.Pointer(r.uint16, Ligature), r.uint16);
15
23
 
24
+ /** @type {import('restructure').VersionedStruct} */
16
25
  let GSUBLookup = new r.VersionedStruct('lookupType', {
17
- 1: new r.VersionedStruct(r.uint16, {// Single Substitution
26
+ 1: new r.VersionedStruct(r.uint16, { // Single Substitution
18
27
  1: {
19
- coverage: new r.Pointer(r.uint16, Coverage),
20
- deltaGlyphID: r.int16
28
+ coverage: new r.Pointer(r.uint16, Coverage),
29
+ deltaGlyphID: r.int16
21
30
  },
22
31
  2: {
23
- coverage: new r.Pointer(r.uint16, Coverage),
24
- glyphCount: r.uint16,
25
- substitute: new r.LazyArray(r.uint16, 'glyphCount')
32
+ coverage: new r.Pointer(r.uint16, Coverage),
33
+ glyphCount: r.uint16,
34
+ substitute: new r.LazyArray(r.uint16, 'glyphCount')
26
35
  }
27
36
  }),
28
37
 
29
38
  2: { // Multiple Substitution
30
- substFormat: r.uint16,
31
- coverage: new r.Pointer(r.uint16, Coverage),
32
- count: r.uint16,
33
- sequences: new r.LazyArray(new r.Pointer(r.uint16, Sequence), 'count')
39
+ substFormat: r.uint16,
40
+ coverage: new r.Pointer(r.uint16, Coverage),
41
+ count: r.uint16,
42
+ sequences: new r.LazyArray(new r.Pointer(r.uint16, Sequence), 'count')
34
43
  },
35
44
 
36
45
  3: { // Alternate Substitution
37
- substFormat: r.uint16,
38
- coverage: new r.Pointer(r.uint16, Coverage),
39
- count: r.uint16,
40
- alternateSet: new r.LazyArray(new r.Pointer(r.uint16, AlternateSet), 'count')
46
+ substFormat: r.uint16,
47
+ coverage: new r.Pointer(r.uint16, Coverage),
48
+ count: r.uint16,
49
+ alternateSet: new r.LazyArray(new r.Pointer(r.uint16, AlternateSet), 'count')
41
50
  },
42
51
 
43
52
  4: { // Ligature Substitution
44
- substFormat: r.uint16,
45
- coverage: new r.Pointer(r.uint16, Coverage),
46
- count: r.uint16,
47
- ligatureSets: new r.LazyArray(new r.Pointer(r.uint16, LigatureSet), 'count')
53
+ substFormat: r.uint16,
54
+ coverage: new r.Pointer(r.uint16, Coverage),
55
+ count: r.uint16,
56
+ ligatureSets: new r.LazyArray(new r.Pointer(r.uint16, LigatureSet), 'count')
48
57
  },
49
58
 
50
- 5: Context, // Contextual Substitution
59
+ 5: Context, // Contextual Substitution
51
60
  6: ChainingContext, // Chaining Contextual Substitution
52
61
 
53
62
  7: { // Extension Substitution
54
- substFormat: r.uint16,
55
- lookupType: r.uint16, // cannot also be 7
56
- extension: new r.Pointer(r.uint32, null)
63
+ substFormat: r.uint16,
64
+ lookupType: r.uint16, // cannot also be 7
65
+ extension: new r.Pointer(r.uint32, null)
57
66
  },
58
67
 
59
68
  8: { // Reverse Chaining Contextual Single Substitution
60
- substFormat: r.uint16,
61
- coverage: new r.Pointer(r.uint16, Coverage),
62
- backtrackGlyphCount: r.uint16,
63
- backtrackCoverage: new r.Array(new r.Pointer(r.uint16, Coverage), 'backtrackGlyphCount'),
64
- lookaheadGlyphCount: r.uint16,
65
- lookaheadCoverage: new r.Array(new r.Pointer(r.uint16, Coverage), 'lookaheadGlyphCount'),
66
- glyphCount: r.uint16,
67
- substitute: new r.LazyArray(r.uint16, 'glyphCount')
69
+ substFormat: r.uint16,
70
+ coverage: new r.Pointer(r.uint16, Coverage),
71
+ backtrackGlyphCount: r.uint16,
72
+ backtrackCoverage: new r.Array(new r.Pointer(r.uint16, Coverage), 'backtrackGlyphCount'),
73
+ lookaheadGlyphCount: r.uint16,
74
+ lookaheadCoverage: new r.Array(new r.Pointer(r.uint16, Coverage), 'lookaheadGlyphCount'),
75
+ glyphCount: r.uint16,
76
+ substitute: new r.LazyArray(r.uint16, 'glyphCount')
68
77
  }
69
78
  });
70
79
 
71
80
  // Fix circular reference
72
- GSUBLookup.versions[7].extension.type = GSUBLookup;
81
+ let gsubExt = /** @type {Record<string, BaseType>} */ (GSUBLookup.versions[7]);
82
+ /** @type {Pointer} */ (gsubExt.extension).type = GSUBLookup;
73
83
 
84
+ /** @type {import('restructure').VersionedStruct} */
74
85
  export default new r.VersionedStruct(r.uint32, {
75
86
  header: {
76
- scriptList: new r.Pointer(r.uint16, ScriptList),
77
- featureList: new r.Pointer(r.uint16, FeatureList),
78
- lookupList: new r.Pointer(r.uint16, new LookupList(GSUBLookup))
87
+ scriptList: new r.Pointer(r.uint16, ScriptList),
88
+ featureList: new r.Pointer(r.uint16, FeatureList),
89
+ lookupList: new r.Pointer(r.uint16, LookupList(GSUBLookup))
79
90
  },
80
91
 
81
92
  0x00010000: {},
@@ -2,30 +2,75 @@ import * as r from 'restructure';
2
2
  import { resolveLength } from 'restructure';
3
3
  import { ItemVariationStore } from './variations';
4
4
 
5
- // TODO: add this to restructure
5
+ /** @typedef {import('restructure').BaseType} BaseType */
6
+ /** @typedef {import('restructure').DecodeStream} DecodeStream */
7
+ /** @typedef {import('restructure').LengthSpec} LengthSpec */
8
+ /** @typedef {import('restructure').StructValue} StructValue */
9
+
10
+ /**
11
+ * Integer whose byte width is computed from a LengthSpec.
12
+ * @implements {BaseType}
13
+ */
6
14
  class VariableSizeNumber {
15
+ /**
16
+ * @param {LengthSpec} size
17
+ */
7
18
  constructor(size) {
19
+ /** @type {LengthSpec} */
8
20
  this._size = size;
9
21
  }
10
22
 
23
+ /**
24
+ * @param {DecodeStream} stream
25
+ * @param {StructValue | null | undefined} parent
26
+ * @returns {number}
27
+ */
11
28
  decode(stream, parent) {
12
29
  switch (this.size(0, parent)) {
13
30
  case 1: return stream.readUInt8();
14
31
  case 2: return stream.readUInt16BE();
15
32
  case 3: return stream.readUInt24BE();
16
33
  case 4: return stream.readUInt32BE();
34
+ default: throw new Error(`Unsupported VariableSizeNumber width`);
17
35
  }
18
36
  }
19
37
 
20
- size(val, parent) {
38
+ /**
39
+ * @param {unknown} _val
40
+ * @param {StructValue | null | undefined} [parent]
41
+ * @returns {number}
42
+ */
43
+ size(_val, parent) {
21
44
  return resolveLength(this._size, null, parent);
22
45
  }
23
46
  }
24
47
 
25
48
  let MapDataEntry = new r.Struct({
26
- entry: new VariableSizeNumber(t => ((t.parent.entryFormat & 0x0030) >> 4) + 1),
27
- outerIndex: t => t.entry >> ((t.parent.entryFormat & 0x000F) + 1),
28
- innerIndex: t => t.entry & ((1 << ((t.parent.entryFormat & 0x000F) + 1)) - 1)
49
+ entry: new VariableSizeNumber(
50
+ /** @param {StructValue} t @returns {number} */
51
+ (t) => {
52
+ let parent = /** @type {StructValue} */ (t.parent);
53
+ return ((/** @type {number} */ (parent.entryFormat) & 0x0030) >> 4) + 1;
54
+ }
55
+ ),
56
+ /**
57
+ * @param {StructValue} t
58
+ * @returns {number}
59
+ */
60
+ outerIndex: (t) => {
61
+ let parent = /** @type {StructValue} */ (t.parent);
62
+ let entryFormat = /** @type {number} */ (parent.entryFormat);
63
+ return /** @type {number} */ (t.entry) >> ((entryFormat & 0x000F) + 1);
64
+ },
65
+ /**
66
+ * @param {StructValue} t
67
+ * @returns {number}
68
+ */
69
+ innerIndex: (t) => {
70
+ let parent = /** @type {StructValue} */ (t.parent);
71
+ let entryFormat = /** @type {number} */ (parent.entryFormat);
72
+ return /** @type {number} */ (t.entry) & ((1 << ((entryFormat & 0x000F) + 1)) - 1);
73
+ }
29
74
  });
30
75
 
31
76
  let DeltaSetIndexMap = new r.Struct({
@@ -34,6 +79,7 @@ let DeltaSetIndexMap = new r.Struct({
34
79
  mapData: new r.Array(MapDataEntry, 'mapCount')
35
80
  });
36
81
 
82
+ /** @type {import('restructure').Struct} */
37
83
  export default new r.Struct({
38
84
  majorVersion: r.uint16,
39
85
  minorVersion: r.uint16,