@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,5 +1,8 @@
1
1
  import * as r from 'restructure';
2
2
 
3
+ /** @typedef {import('restructure').BaseType} BaseType */
4
+
5
+ /** @type {import('restructure').Struct} */
3
6
  export let BigMetrics = new r.Struct({
4
7
  height: r.uint8,
5
8
  width: r.uint8,
@@ -11,6 +14,7 @@ export let BigMetrics = new r.Struct({
11
14
  vertAdvance: r.uint8
12
15
  });
13
16
 
17
+ /** @type {import('restructure').Struct} */
14
18
  export let SmallMetrics = new r.Struct({
15
19
  height: r.uint8,
16
20
  width: r.uint8,
@@ -25,10 +29,13 @@ let EBDTComponent = new r.Struct({
25
29
  yOffset: r.int8
26
30
  });
27
31
 
28
- class ByteAligned {}
29
-
30
- class BitAligned {}
32
+ /** Marker codecs for bitmap payload layout (decoded by glyph consumers). */
33
+ /** @type {BaseType} */
34
+ const ByteAligned = {};
35
+ /** @type {BaseType} */
36
+ const BitAligned = {};
31
37
 
38
+ /** @type {import('restructure').VersionedStruct} */
32
39
  export let glyph = new r.VersionedStruct('version', {
33
40
  1: {
34
41
  metrics: SmallMetrics,
@@ -1,6 +1,8 @@
1
1
  import * as r from 'restructure';
2
2
  import { BigMetrics } from './EBDT';
3
3
 
4
+ /** @typedef {import('restructure').StructValue} StructValue */
5
+
4
6
  let SBitLineMetrics = new r.Struct({
5
7
  ascender: r.int8,
6
8
  descender: r.int8,
@@ -20,6 +22,17 @@ let CodeOffsetPair = new r.Struct({
20
22
  offset: r.uint16
21
23
  });
22
24
 
25
+ /**
26
+ * Spec: numOffsets = lastGlyphIndex - firstGlyphIndex + 2 (extra sentinel for last glyph size).
27
+ * @param {StructValue} t
28
+ * @returns {number}
29
+ */
30
+ function glyphRangeOffsetCount(t) {
31
+ let parent = /** @type {StructValue} */ (t.parent);
32
+ return /** @type {number} */ (parent.lastGlyphIndex)
33
+ - /** @type {number} */ (parent.firstGlyphIndex) + 2;
34
+ }
35
+
23
36
  let IndexSubtable = new r.VersionedStruct(r.uint16, {
24
37
  header: {
25
38
  imageFormat: r.uint16,
@@ -27,7 +40,7 @@ let IndexSubtable = new r.VersionedStruct(r.uint16, {
27
40
  },
28
41
 
29
42
  1: {
30
- offsetArray: new r.Array(r.uint32, t => t.parent.lastGlyphIndex - t.parent.firstGlyphIndex + 1)
43
+ offsetArray: new r.Array(r.uint32, glyphRangeOffsetCount)
31
44
  },
32
45
 
33
46
  2: {
@@ -36,30 +49,67 @@ let IndexSubtable = new r.VersionedStruct(r.uint16, {
36
49
  },
37
50
 
38
51
  3: {
39
- offsetArray: new r.Array(r.uint16, t => t.parent.lastGlyphIndex - t.parent.firstGlyphIndex + 1)
52
+ offsetArray: new r.Array(r.uint16, glyphRangeOffsetCount),
53
+ // Format 3 pads to 32-bit alignment when the offset count is odd.
54
+ pad: new r.Reserved(
55
+ r.uint16,
56
+ /** @param {StructValue} t @returns {number} */
57
+ t => glyphRangeOffsetCount(t) % 2
58
+ )
40
59
  },
41
60
 
42
61
  4: {
43
62
  numGlyphs: r.uint32,
44
- glyphArray: new r.Array(CodeOffsetPair, t => t.numGlyphs + 1)
63
+ glyphArray: new r.Array(
64
+ CodeOffsetPair,
65
+ /** @param {StructValue} t @returns {number} */
66
+ t => /** @type {number} */ (t.numGlyphs) + 1
67
+ )
45
68
  },
46
69
 
47
70
  5: {
48
71
  imageSize: r.uint32,
49
72
  bigMetrics: BigMetrics,
50
73
  numGlyphs: r.uint32,
51
- glyphCodeArray: new r.Array(r.uint16, 'numGlyphs')
74
+ glyphCodeArray: new r.Array(r.uint16, 'numGlyphs'),
75
+ // Format 5 pads to 32-bit alignment when glyphCodeArray length is odd.
76
+ pad: new r.Reserved(
77
+ r.uint16,
78
+ /** @param {StructValue} t @returns {number} */
79
+ t => /** @type {number} */ (t.numGlyphs) % 2
80
+ )
52
81
  }
53
82
  });
54
83
 
55
- let IndexSubtableArray = new r.Struct({
84
+ let IndexSubtableRecord = new r.Struct({
56
85
  firstGlyphIndex: r.uint16,
57
86
  lastGlyphIndex: r.uint16,
58
- subtable: new r.Pointer(r.uint32, IndexSubtable)
87
+ // Offset from the start of IndexSubTableList (OpenType IndexSubTableArray).
88
+ subtable: new r.Pointer(r.uint32, IndexSubtable, { type: 'parent' })
89
+ });
90
+
91
+ /**
92
+ * Wrapper so record pointers resolve relative to the list start.
93
+ * process() on BitmapSizeTable unwraps `.tables` so the public shape stays an array.
94
+ */
95
+ let IndexSubTableList = new r.Struct({
96
+ tables: new r.Array(
97
+ IndexSubtableRecord,
98
+ /** @param {StructValue} t @returns {number} */
99
+ t => /** @type {number} */ (/** @type {StructValue} */ (t.parent).numberOfIndexSubTables)
100
+ )
59
101
  });
60
102
 
103
+ /**
104
+ * @typedef {StructValue & {
105
+ * indexSubTableArray: { tables: StructValue[] } | StructValue[],
106
+ * numberOfIndexSubTables: number
107
+ * }} BitmapSizeTableValue
108
+ */
109
+
61
110
  let BitmapSizeTable = new r.Struct({
62
- indexSubTableArray: new r.Pointer(r.uint32, new r.Array(IndexSubtableArray, 1), { type: 'parent' }),
111
+ // Lazy: numberOfIndexSubTables is stored after this pointer in the binary layout.
112
+ indexSubTableArray: new r.Pointer(r.uint32, IndexSubTableList, { type: 'parent', lazy: true }),
63
113
  indexTablesSize: r.uint32,
64
114
  numberOfIndexSubTables: r.uint32,
65
115
  colorRef: r.uint32,
@@ -73,6 +123,16 @@ let BitmapSizeTable = new r.Struct({
73
123
  flags: new r.Bitfield(r.uint8, ['horizontal', 'vertical'])
74
124
  });
75
125
 
126
+ BitmapSizeTable.process = function () {
127
+ let self = /** @type {BitmapSizeTableValue} */ (this);
128
+ // Access forces lazy decode now that numberOfIndexSubTables is available.
129
+ let list = self.indexSubTableArray;
130
+ if (list && !Array.isArray(list) && Array.isArray(list.tables)) {
131
+ self.indexSubTableArray = list.tables;
132
+ }
133
+ };
134
+
135
+ /** @type {import('restructure').Struct} */
76
136
  export default new r.Struct({
77
137
  version: r.uint32, // 0x00020000
78
138
  numSizes: r.uint32,
@@ -38,6 +38,7 @@ let MarkGlyphSetsDef = new r.Struct({
38
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
44
  glyphClassDef: new r.Pointer(r.uint16, ClassDef),
@@ -2,6 +2,12 @@ import * as r from 'restructure';
2
2
  import { ScriptList, FeatureList, LookupList, Coverage, ClassDef, Device, Context, ChainingContext } from './opentype';
3
3
  import { FeatureVariations } from './variations';
4
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 */
10
+
5
11
  let ValueFormat = new r.Bitfield(r.uint16, [
6
12
  'xPlacement', 'yPlacement',
7
13
  'xAdvance', 'yAdvance',
@@ -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
22
  xAdvance: r.int16,
16
23
  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 })
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,12 +83,25 @@ 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
  }
@@ -102,13 +152,24 @@ let MarkRecord = new r.Struct({
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);
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
+ );
106
160
  let BaseArray = new r.Array(BaseRecord, r.uint16);
107
161
 
108
- let ComponentRecord = new r.Array(new r.Pointer(r.uint16, Anchor), t => t.parent.parent.classCount);
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
+ );
109
169
  let LigatureAttach = new r.Array(ComponentRecord, r.uint16);
110
170
  let LigatureArray = new r.Array(new r.Pointer(r.uint16, LigatureAttach), r.uint16);
111
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
@@ -190,13 +251,15 @@ let GPOSLookup = new r.VersionedStruct('lookupType', {
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
260
  scriptList: new r.Pointer(r.uint16, ScriptList),
198
261
  featureList: new r.Pointer(r.uint16, FeatureList),
199
- lookupList: new r.Pointer(r.uint16, new LookupList(GPOSLookup))
262
+ lookupList: new r.Pointer(r.uint16, LookupList(GPOSLookup))
200
263
  },
201
264
 
202
265
  0x00010000: {},
@@ -2,17 +2,26 @@ import * as r from 'restructure';
2
2
  import { ScriptList, FeatureList, LookupList, Coverage, Context, ChainingContext } from './opentype';
3
3
  import { FeatureVariations } from './variations';
4
4
 
5
+ /** @typedef {import('restructure').BaseType} BaseType */
6
+ /** @typedef {import('restructure').Pointer} Pointer */
7
+ /** @typedef {import('restructure').StructValue} StructValue */
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
13
  glyph: r.uint16,
10
14
  compCount: r.uint16,
11
- components: new r.Array(r.uint16, t => t.compCount - 1)
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
26
  1: new r.VersionedStruct(r.uint16, { // Single Substitution
18
27
  1: {
@@ -69,13 +78,15 @@ let GSUBLookup = new r.VersionedStruct('lookupType', {
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
87
  scriptList: new r.Pointer(r.uint16, ScriptList),
77
88
  featureList: new r.Pointer(r.uint16, FeatureList),
78
- lookupList: new r.Pointer(r.uint16, new LookupList(GSUBLookup))
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,
@@ -9,12 +9,12 @@ let JstfPriority = new r.Struct({
9
9
  shrinkageDisableGSUB: new r.Pointer(r.uint16, JstfGSUBModList),
10
10
  shrinkageEnableGPOS: new r.Pointer(r.uint16, JstfGSUBModList),
11
11
  shrinkageDisableGPOS: new r.Pointer(r.uint16, JstfGSUBModList),
12
- shrinkageJstfMax: new r.Pointer(r.uint16, new LookupList(GPOSLookup)),
12
+ shrinkageJstfMax: new r.Pointer(r.uint16, LookupList(GPOSLookup)),
13
13
  extensionEnableGSUB: new r.Pointer(r.uint16, JstfGSUBModList),
14
14
  extensionDisableGSUB: new r.Pointer(r.uint16, JstfGSUBModList),
15
15
  extensionEnableGPOS: new r.Pointer(r.uint16, JstfGSUBModList),
16
16
  extensionDisableGPOS: new r.Pointer(r.uint16, JstfGSUBModList),
17
- extensionJstfMax: new r.Pointer(r.uint16, new LookupList(GPOSLookup))
17
+ extensionJstfMax: new r.Pointer(r.uint16, LookupList(GPOSLookup))
18
18
  });
19
19
 
20
20
  let JstfLangSys = new r.Array(new r.Pointer(r.uint16, JstfPriority), r.uint16);
@@ -36,6 +36,7 @@ let JstfScriptRecord = new r.Struct({
36
36
  script: new r.Pointer(r.uint16, JstfScript, { type: 'parent' })
37
37
  });
38
38
 
39
+ /** @type {import('restructure').Struct} */
39
40
  export default new r.Struct({
40
41
  version: r.uint32, // should be 0x00010000
41
42
  scriptCount: r.uint16,
@@ -3,6 +3,7 @@ import * as r from 'restructure';
3
3
  // Linear Threshold table
4
4
  // Records the ppem for each glyph at which the scaling becomes linear again,
5
5
  // despite instructions effecting the advance width
6
+ /** @type {import('restructure').Struct} */
6
7
  export default new r.Struct({
7
8
  version: r.uint16,
8
9
  numGlyphs: r.uint16,
package/src/tables/OS2.js CHANGED
@@ -1,5 +1,6 @@
1
1
  import * as r from 'restructure';
2
2
 
3
+ /** @type {import('restructure').VersionedStruct} */
3
4
  var OS2 = new r.VersionedStruct(r.uint16, {
4
5
  header: {
5
6
  xAvgCharWidth: r.int16, // average weighted advance width of lower case letters and space
@@ -2,6 +2,7 @@ import * as r from 'restructure';
2
2
 
3
3
  // PCL 5 Table
4
4
  // NOTE: The PCLT table is strongly discouraged for OpenType fonts with TrueType outlines
5
+ /** @type {import('restructure').Struct} */
5
6
  export default new r.Struct({
6
7
  version: r.uint16,
7
8
  fontNumber: r.uint32,
@@ -1,5 +1,10 @@
1
1
  import * as r from 'restructure';
2
2
 
3
+ /** @typedef {import('restructure').BaseType} BaseType */
4
+ /** @typedef {import('restructure').DecodeStream} DecodeStream */
5
+ /** @typedef {import('restructure').EncodeStream} EncodeStream */
6
+ /** @typedef {import('restructure').StructValue} StructValue */
7
+
3
8
  let AxisRecord = new r.Struct({
4
9
  axisTag: new r.String(4),
5
10
  axisNameID: r.uint16,
@@ -41,19 +46,40 @@ let AxisValue = new r.VersionedStruct(r.uint16, {
41
46
  });
42
47
 
43
48
  let AxisValueArray = new r.Struct({
44
- axisValues: new r.Array(new r.Pointer(r.uint16, AxisValue), t => t.parent.axisValueCount)
49
+ axisValues: new r.Array(
50
+ new r.Pointer(r.uint16, AxisValue),
51
+ /** @param {StructValue} t @returns {number} */
52
+ t => /** @type {number} */ (/** @type {StructValue} */ (t.parent).axisValueCount)
53
+ )
45
54
  });
46
55
 
47
- // Use designAxisSize as record stride (OpenType forward-compat).
56
+ /**
57
+ * Design-axis array whose record stride is designAxisSize (OpenType forward-compat).
58
+ * @implements {BaseType}
59
+ */
48
60
  class DesignAxisArray {
61
+ /**
62
+ * @param {StructValue | null | undefined} parent
63
+ * @returns {number}
64
+ */
49
65
  _stride(parent) {
50
66
  // Spec requires room for Tag + 2×uint16 (8 bytes); never shrink below that.
51
- return Math.max(8, parent.designAxisSize ?? parent.val?.designAxisSize ?? 8);
67
+ let fromParent = parent ? /** @type {number | undefined} */ (parent.designAxisSize) : undefined;
68
+ let fromVal = parent && parent.val
69
+ ? /** @type {number | undefined} */ (/** @type {StructValue} */ (parent.val).designAxisSize)
70
+ : undefined;
71
+ return Math.max(8, fromParent ?? fromVal ?? 8);
52
72
  }
53
73
 
74
+ /**
75
+ * @param {DecodeStream} stream
76
+ * @param {StructValue | null | undefined} parent
77
+ * @returns {StructValue[]}
78
+ */
54
79
  decode(stream, parent) {
55
- let count = parent.designAxisCount;
80
+ let count = parent ? /** @type {number} */ (parent.designAxisCount) : 0;
56
81
  let size = this._stride(parent);
82
+ /** @type {StructValue[]} */
57
83
  let res = [];
58
84
  for (let i = 0; i < count; i++) {
59
85
  let start = stream.pos;
@@ -63,13 +89,26 @@ class DesignAxisArray {
63
89
  return res;
64
90
  }
65
91
 
92
+ /**
93
+ * @param {unknown} array
94
+ * @param {StructValue | null | undefined} parent
95
+ * @returns {number}
96
+ */
66
97
  size(array, parent) {
67
- return (array?.length ?? 0) * this._stride(parent);
98
+ let len = Array.isArray(array) ? array.length : 0;
99
+ return len * this._stride(parent);
68
100
  }
69
101
 
102
+ /**
103
+ * @param {EncodeStream} stream
104
+ * @param {unknown} array
105
+ * @param {StructValue | null | undefined} parent
106
+ * @returns {void}
107
+ */
70
108
  encode(stream, array, parent) {
71
109
  let size = this._stride(parent);
72
- for (let item of array) {
110
+ let items = Array.isArray(array) ? /** @type {StructValue[]} */ (array) : [];
111
+ for (let item of items) {
73
112
  let start = stream.pos;
74
113
  AxisRecord.encode(stream, item, parent);
75
114
  let pad = size - (stream.pos - start);
@@ -80,6 +119,7 @@ class DesignAxisArray {
80
119
  }
81
120
  }
82
121
 
122
+ /** @type {import('restructure').VersionedStruct} */
83
123
  export default new r.VersionedStruct(r.uint32, {
84
124
  header: {
85
125
  designAxisSize: r.uint16,
@@ -23,6 +23,7 @@ let VdmxGroup = new r.Struct({
23
23
  entries: new r.Array(vTable, 'recs') // The VDMX records
24
24
  });
25
25
 
26
+ /** @type {import('restructure').Struct} */
26
27
  export default new r.Struct({
27
28
  version: r.uint16, // Version number (0 or 1)
28
29
  numRecs: r.uint16, // Number of VDMX groups present
@@ -5,6 +5,7 @@ let VerticalOrigin = new r.Struct({
5
5
  vertOriginY: r.int16
6
6
  });
7
7
 
8
+ /** @type {import('restructure').Struct} */
8
9
  export default new r.Struct({
9
10
  majorVersion: r.uint16,
10
11
  minorVersion: r.uint16,