@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
package/src/cff/CFFTop.js CHANGED
@@ -8,33 +8,89 @@ import { StandardEncoding, ExpertEncoding } from './CFFEncodings';
8
8
  import { ISOAdobeCharset, ExpertCharset, ExpertSubsetCharset } from './CFFCharsets';
9
9
  import { ItemVariationStore } from '../tables/variations';
10
10
 
11
+ /** @typedef {import('restructure').BaseType} BaseType */
12
+ /** @typedef {import('restructure').DecodeStream} DecodeStream */
13
+ /** @typedef {import('restructure').EncodeStream} EncodeStream */
14
+ /** @typedef {import('restructure').StructValue} StructValue */
15
+ /** @typedef {import('../../types/fontkit').CFFEncodeContext} CFFEncodeContext */
16
+
17
+ /**
18
+ * @param {StructValue} t
19
+ * @returns {number}
20
+ */
21
+ function charStringsCount(t) {
22
+ let parent = t.parent;
23
+ if (!parent) {
24
+ return 0;
25
+ }
26
+ let cs = parent.CharStrings;
27
+ if (cs && typeof cs === 'object' && 'length' in cs && typeof /** @type {{ length: unknown }} */ (cs).length === 'number') {
28
+ return /** @type {{ length: number }} */ (cs).length;
29
+ }
30
+ return 0;
31
+ }
32
+
11
33
  // Checks if an operand is an index of a predefined value,
12
34
  // otherwise delegates to the provided type.
13
35
  class PredefinedOp {
36
+ /**
37
+ * @param {unknown[]} predefinedOps
38
+ * @param {BaseType} type
39
+ */
14
40
  constructor(predefinedOps, type) {
41
+ /** @type {unknown[]} */
15
42
  this.predefinedOps = predefinedOps;
43
+ /** @type {BaseType} */
16
44
  this.type = type;
17
45
  }
18
46
 
47
+ /**
48
+ * @param {DecodeStream} stream
49
+ * @param {StructValue} parent
50
+ * @param {number[]} operands
51
+ * @returns {unknown}
52
+ */
19
53
  decode(stream, parent, operands) {
20
- if (this.predefinedOps[operands[0]]) {
54
+ if (this.predefinedOps[operands[0]] != null) {
21
55
  return this.predefinedOps[operands[0]];
22
56
  }
23
57
 
58
+ if (!this.type.decode) {
59
+ throw new Error('PredefinedOp type must implement decode()');
60
+ }
24
61
  return this.type.decode(stream, parent, operands);
25
62
  }
26
63
 
64
+ /**
65
+ * @param {unknown} value
66
+ * @param {StructValue | null | undefined} ctx
67
+ * @returns {unknown}
68
+ */
27
69
  size(value, ctx) {
70
+ if (!this.type.size) {
71
+ throw new Error('PredefinedOp type must implement size()');
72
+ }
28
73
  return this.type.size(value, ctx);
29
74
  }
30
75
 
76
+ /**
77
+ * @param {EncodeStream | null} stream
78
+ * @param {unknown} value
79
+ * @param {StructValue | null | undefined} ctx
80
+ * @returns {unknown[]}
81
+ */
31
82
  encode(stream, value, ctx) {
32
83
  let index = this.predefinedOps.indexOf(value);
33
84
  if (index !== -1) {
34
- return index;
85
+ // Must be an operand list — CFFDict iterates with for-of.
86
+ return [index];
35
87
  }
36
88
 
37
- return this.type.encode(stream, value, ctx);
89
+ if (!this.type.encode) {
90
+ throw new Error('PredefinedOp type must implement encode()');
91
+ }
92
+ let encoded = this.type.encode(stream, value, ctx);
93
+ return Array.isArray(encoded) ? encoded : [encoded];
38
94
  }
39
95
  }
40
96
 
@@ -43,6 +99,10 @@ class CFFEncodingVersion extends r.Number {
43
99
  super('UInt8');
44
100
  }
45
101
 
102
+ /**
103
+ * @param {DecodeStream} stream
104
+ * @returns {number}
105
+ */
46
106
  decode(stream) {
47
107
  return r.uint8.decode(stream) & 0x7f;
48
108
  }
@@ -72,20 +132,34 @@ let CFFCustomEncoding = new r.VersionedStruct(new CFFEncodingVersion(), {
72
132
  // TODO: supplement?
73
133
  });
74
134
 
75
- let CFFEncoding = new PredefinedOp([ StandardEncoding, ExpertEncoding ], new CFFPointer(CFFCustomEncoding, { lazy: true }));
135
+ let CFFEncoding = new PredefinedOp([StandardEncoding, ExpertEncoding], new CFFPointer(CFFCustomEncoding, { lazy: true }));
76
136
 
77
137
  // Decodes an array of ranges until the total
78
138
  // length is equal to the provided length.
79
139
  class RangeArray extends r.Array {
140
+ /**
141
+ * @param {DecodeStream} stream
142
+ * @param {StructValue} parent
143
+ * @returns {Array<StructValue & { nLeft: number, offset: number }>}
144
+ */
80
145
  decode(stream, parent) {
146
+ if (this.length == null) {
147
+ throw new Error('RangeArray requires a length');
148
+ }
81
149
  let length = resolveLength(this.length, stream, parent);
82
150
  let count = 0;
151
+ /** @type {Array<StructValue & { nLeft: number, offset: number }>} */
83
152
  let res = [];
84
153
  while (count < length) {
85
- let range = this.type.decode(stream, parent);
154
+ if (!this.type.decode) {
155
+ throw new Error('RangeArray element type must implement decode()');
156
+ }
157
+ let range = /** @type {StructValue & { nLeft: number, offset?: number }} */ (
158
+ this.type.decode(stream, parent)
159
+ );
86
160
  range.offset = count;
87
161
  count += range.nLeft + 1;
88
- res.push(range);
162
+ res.push(/** @type {StructValue & { nLeft: number, offset: number }} */ (range));
89
163
  }
90
164
 
91
165
  return res;
@@ -94,19 +168,19 @@ class RangeArray extends r.Array {
94
168
 
95
169
  let CFFCustomCharset = new r.VersionedStruct(r.uint8, {
96
170
  0: {
97
- glyphs: new r.Array(r.uint16, t => t.parent.CharStrings.length - 1)
171
+ glyphs: new r.Array(r.uint16, t => charStringsCount(t) - 1)
98
172
  },
99
173
 
100
174
  1: {
101
- ranges: new RangeArray(Range1, t => t.parent.CharStrings.length - 1)
175
+ ranges: new RangeArray(Range1, t => charStringsCount(t) - 1)
102
176
  },
103
177
 
104
178
  2: {
105
- ranges: new RangeArray(Range2, t => t.parent.CharStrings.length - 1)
179
+ ranges: new RangeArray(Range2, t => charStringsCount(t) - 1)
106
180
  }
107
181
  });
108
182
 
109
- let CFFCharset = new PredefinedOp([ ISOAdobeCharset, ExpertCharset, ExpertSubsetCharset ], new CFFPointer(CFFCustomCharset, {lazy: true}));
183
+ let CFFCharset = new PredefinedOp([ISOAdobeCharset, ExpertCharset, ExpertSubsetCharset], new CFFPointer(CFFCustomCharset, { lazy: true }));
110
184
 
111
185
  let FDRange3 = new r.Struct({
112
186
  first: r.uint16,
@@ -120,7 +194,7 @@ let FDRange4 = new r.Struct({
120
194
 
121
195
  let FDSelect = new r.VersionedStruct(r.uint8, {
122
196
  0: {
123
- fds: new r.Array(r.uint8, t => t.parent.CharStrings.length)
197
+ fds: new r.Array(r.uint8, t => charStringsCount(t))
124
198
  },
125
199
 
126
200
  3: {
@@ -138,15 +212,34 @@ let FDSelect = new r.VersionedStruct(r.uint8, {
138
212
 
139
213
  let ptr = new CFFPointer(CFFPrivateDict);
140
214
  class CFFPrivateOp {
215
+ /**
216
+ * @param {DecodeStream} stream
217
+ * @param {StructValue} parent
218
+ * @param {number[]} operands
219
+ * @returns {unknown}
220
+ */
141
221
  decode(stream, parent, operands) {
142
222
  parent.length = operands[0];
143
223
  return ptr.decode(stream, parent, [operands[1]]);
144
224
  }
145
225
 
226
+ /**
227
+ * Size operands match encode(null, …): [privateDictByteLength, pointerOperand].
228
+ * @param {StructValue} dict
229
+ * @param {CFFEncodeContext | StructValue} ctx
230
+ * @returns {unknown[]}
231
+ */
146
232
  size(dict, ctx) {
147
- return [CFFPrivateDict.size(dict, ctx, false), ptr.size(dict, ctx)[0]];
233
+ // Delegate to encode(null) so pointerSize is updated and operands match.
234
+ return this.encode(null, dict, ctx);
148
235
  }
149
236
 
237
+ /**
238
+ * @param {EncodeStream | null} stream
239
+ * @param {StructValue} dict
240
+ * @param {CFFEncodeContext | StructValue} ctx
241
+ * @returns {unknown[]}
242
+ */
150
243
  encode(stream, dict, ctx) {
151
244
  return [CFFPrivateDict.size(dict, ctx, false), ptr.encode(stream, dict, ctx)[0]];
152
245
  }
@@ -154,82 +247,82 @@ class CFFPrivateOp {
154
247
 
155
248
  let FontDict = new CFFDict([
156
249
  // key name type(s) default
157
- [18, 'Private', new CFFPrivateOp, null],
158
- [[12, 38], 'FontName', 'sid', null],
159
- [[12, 7], 'FontMatrix', 'array', [0.001, 0, 0, 0.001, 0, 0]],
160
- [[12, 5], 'PaintType', 'number', 0],
250
+ [18, 'Private', new CFFPrivateOp(), null],
251
+ [[12, 38], 'FontName', 'sid', null],
252
+ [[12, 7], 'FontMatrix', 'array', [0.001, 0, 0, 0.001, 0, 0]],
253
+ [[12, 5], 'PaintType', 'number', 0]
161
254
  ]);
162
255
 
163
256
  let CFFTopDict = new CFFDict([
164
257
  // key name type(s) default
165
- [[12, 30], 'ROS', ['sid', 'sid', 'number'], null],
166
-
167
- [0, 'version', 'sid', null],
168
- [1, 'Notice', 'sid', null],
169
- [[12, 0], 'Copyright', 'sid', null],
170
- [2, 'FullName', 'sid', null],
171
- [3, 'FamilyName', 'sid', null],
172
- [4, 'Weight', 'sid', null],
173
- [[12, 1], 'isFixedPitch', 'boolean', false],
174
- [[12, 2], 'ItalicAngle', 'number', 0],
175
- [[12, 3], 'UnderlinePosition', 'number', -100],
176
- [[12, 4], 'UnderlineThickness', 'number', 50],
177
- [[12, 5], 'PaintType', 'number', 0],
178
- [[12, 6], 'CharstringType', 'number', 2],
179
- [[12, 7], 'FontMatrix', 'array', [0.001, 0, 0, 0.001, 0, 0]],
180
- [13, 'UniqueID', 'number', null],
181
- [5, 'FontBBox', 'array', [0, 0, 0, 0]],
182
- [[12, 8], 'StrokeWidth', 'number', 0],
183
- [14, 'XUID', 'array', null],
184
- [15, 'charset', CFFCharset, ISOAdobeCharset],
185
- [16, 'Encoding', CFFEncoding, StandardEncoding],
186
- [17, 'CharStrings', new CFFPointer(new CFFIndex), null],
187
- [18, 'Private', new CFFPrivateOp, null],
188
- [[12, 20], 'SyntheticBase', 'number', null],
189
- [[12, 21], 'PostScript', 'sid', null],
190
- [[12, 22], 'BaseFontName', 'sid', null],
191
- [[12, 23], 'BaseFontBlend', 'delta', null],
258
+ [[12, 30], 'ROS', ['sid', 'sid', 'number'], null],
259
+
260
+ [0, 'version', 'sid', null],
261
+ [1, 'Notice', 'sid', null],
262
+ [[12, 0], 'Copyright', 'sid', null],
263
+ [2, 'FullName', 'sid', null],
264
+ [3, 'FamilyName', 'sid', null],
265
+ [4, 'Weight', 'sid', null],
266
+ [[12, 1], 'isFixedPitch', 'boolean', false],
267
+ [[12, 2], 'ItalicAngle', 'number', 0],
268
+ [[12, 3], 'UnderlinePosition', 'number', -100],
269
+ [[12, 4], 'UnderlineThickness', 'number', 50],
270
+ [[12, 5], 'PaintType', 'number', 0],
271
+ [[12, 6], 'CharstringType', 'number', 2],
272
+ [[12, 7], 'FontMatrix', 'array', [0.001, 0, 0, 0.001, 0, 0]],
273
+ [13, 'UniqueID', 'number', null],
274
+ [5, 'FontBBox', 'array', [0, 0, 0, 0]],
275
+ [[12, 8], 'StrokeWidth', 'number', 0],
276
+ [14, 'XUID', 'array', null],
277
+ [15, 'charset', CFFCharset, ISOAdobeCharset],
278
+ [16, 'Encoding', CFFEncoding, StandardEncoding],
279
+ [17, 'CharStrings', new CFFPointer(new CFFIndex()), null],
280
+ [18, 'Private', new CFFPrivateOp(), null],
281
+ [[12, 20], 'SyntheticBase', 'number', null],
282
+ [[12, 21], 'PostScript', 'sid', null],
283
+ [[12, 22], 'BaseFontName', 'sid', null],
284
+ [[12, 23], 'BaseFontBlend', 'delta', null],
192
285
 
193
286
  // CID font specific
194
- [[12, 31], 'CIDFontVersion', 'number', 0],
195
- [[12, 32], 'CIDFontRevision', 'number', 0],
196
- [[12, 33], 'CIDFontType', 'number', 0],
197
- [[12, 34], 'CIDCount', 'number', 8720],
198
- [[12, 35], 'UIDBase', 'number', null],
199
- [[12, 37], 'FDSelect', new CFFPointer(FDSelect), null],
200
- [[12, 36], 'FDArray', new CFFPointer(new CFFIndex(FontDict)), null],
201
- [[12, 38], 'FontName', 'sid', null]
287
+ [[12, 31], 'CIDFontVersion', 'number', 0],
288
+ [[12, 32], 'CIDFontRevision', 'number', 0],
289
+ [[12, 33], 'CIDFontType', 'number', 0],
290
+ [[12, 34], 'CIDCount', 'number', 8720],
291
+ [[12, 35], 'UIDBase', 'number', null],
292
+ [[12, 37], 'FDSelect', new CFFPointer(FDSelect), null],
293
+ [[12, 36], 'FDArray', new CFFPointer(new CFFIndex(FontDict)), null],
294
+ [[12, 38], 'FontName', 'sid', null]
202
295
  ]);
203
296
 
204
297
  let VariationStore = new r.Struct({
205
298
  length: r.uint16,
206
299
  itemVariationStore: ItemVariationStore
207
- })
300
+ });
208
301
 
209
302
  let CFF2TopDict = new CFFDict([
210
- [[12, 7], 'FontMatrix', 'array', [0.001, 0, 0, 0.001, 0, 0]],
211
- [17, 'CharStrings', new CFFPointer(new CFFIndex), null],
212
- [[12, 37], 'FDSelect', new CFFPointer(FDSelect), null],
213
- [[12, 36], 'FDArray', new CFFPointer(new CFFIndex(FontDict)), null],
214
- [24, 'vstore', new CFFPointer(VariationStore), null],
215
- [25, 'maxstack', 'number', 193]
303
+ [[12, 7], 'FontMatrix', 'array', [0.001, 0, 0, 0.001, 0, 0]],
304
+ [17, 'CharStrings', new CFFPointer(new CFFIndex()), null],
305
+ [[12, 37], 'FDSelect', new CFFPointer(FDSelect), null],
306
+ [[12, 36], 'FDArray', new CFFPointer(new CFFIndex(FontDict)), null],
307
+ [24, 'vstore', new CFFPointer(VariationStore), null],
308
+ [25, 'maxstack', 'number', 193]
216
309
  ]);
217
310
 
218
311
  let CFFTop = new r.VersionedStruct(r.fixed16, {
219
312
  1: {
220
- hdrSize: r.uint8,
221
- offSize: r.uint8,
222
- nameIndex: new CFFIndex(new r.String('length')),
223
- topDictIndex: new CFFIndex(CFFTopDict),
224
- stringIndex: new CFFIndex(new r.String('length')),
225
- globalSubrIndex: new CFFIndex
313
+ hdrSize: r.uint8,
314
+ offSize: r.uint8,
315
+ nameIndex: new CFFIndex(new r.String('length')),
316
+ topDictIndex: new CFFIndex(CFFTopDict),
317
+ stringIndex: new CFFIndex(new r.String('length')),
318
+ globalSubrIndex: new CFFIndex()
226
319
  },
227
320
 
228
321
  2: {
229
- hdrSize: r.uint8,
230
- length: r.uint16,
231
- topDict: CFF2TopDict,
232
- globalSubrIndex: new CFFIndex
322
+ hdrSize: r.uint8,
323
+ length: r.uint16,
324
+ topDict: CFF2TopDict,
325
+ globalSubrIndex: new CFFIndex()
233
326
  }
234
327
  });
235
328
 
package/src/decorators.js CHANGED
@@ -1,36 +1,55 @@
1
1
  /**
2
- * This decorator caches the results of a getter or method such that
3
- * the results are lazily computed once, and then cached.
4
- * @private
2
+ * Cache decorator for getters/methods.
3
+ * Results are lazily computed once, then cached on the instance.
4
+ *
5
+ * @template T
6
+ * @param {object} target
7
+ * @param {string} key
8
+ * @param {TypedPropertyDescriptor<T>} descriptor
9
+ * @returns {TypedPropertyDescriptor<T> | void}
5
10
  */
6
11
  export function cache(target, key, descriptor) {
7
12
  if (descriptor.get) {
8
13
  let get = descriptor.get;
9
- descriptor.get = function() {
14
+ descriptor.get = function () {
10
15
  let value = get.call(this);
11
16
  Object.defineProperty(this, key, { value });
12
17
  return value;
13
18
  };
14
- } else if (typeof descriptor.value === 'function') {
15
- let fn = descriptor.value;
19
+ return;
20
+ }
21
+
22
+ if (typeof descriptor.value === 'function') {
23
+ let fn = /** @type {(...args: unknown[]) => T} */ (descriptor.value);
16
24
 
17
- return {
25
+ /** @type {TypedPropertyDescriptor<T>} */
26
+ let replacement = {
27
+ configurable: true,
28
+ enumerable: false,
18
29
  get() {
19
- let cache = new Map;
20
- function memoized(...args) {
21
- let key = args.length > 0 ? args[0] : 'value';
22
- if (cache.has(key)) {
23
- return cache.get(key);
30
+ /** @type {Map<unknown, T>} */
31
+ let cacheMap = new Map();
32
+
33
+ /**
34
+ * @param {...unknown} args
35
+ * @returns {T}
36
+ */
37
+ let memoized = (...args) => {
38
+ let cacheKey = args.length > 0 ? args[0] : 'value';
39
+ if (cacheMap.has(cacheKey)) {
40
+ return /** @type {T} */ (cacheMap.get(cacheKey));
24
41
  }
25
42
 
26
43
  let result = fn.apply(this, args);
27
- cache.set(key, result);
44
+ cacheMap.set(cacheKey, result);
28
45
  return result;
29
46
  };
30
47
 
31
- Object.defineProperty(this, key, {value: memoized});
32
- return memoized;
48
+ Object.defineProperty(this, key, { value: memoized });
49
+ return /** @type {T} */ (/** @type {unknown} */ (memoized));
33
50
  }
34
51
  };
52
+
53
+ return replacement;
35
54
  }
36
55
  }