@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,14 +1,20 @@
1
+ /** @typedef {import('../../types/fontkit').FontLike} FontLike */
2
+ /** @typedef {import('../../types/fontkit').GlyphPoint} GlyphPoint */
3
+ /** @typedef {import('../../types/fontkit').HVARTable} HVARTable */
4
+ /** @typedef {import('../../types/fontkit').ItemVariationStore} ItemVariationStore */
5
+ /** @typedef {import('../../types/fontkit').ItemVariationData} ItemVariationData */
6
+
1
7
  const TUPLES_SHARE_POINT_NUMBERS = 0x8000;
2
- const TUPLE_COUNT_MASK = 0x0fff;
3
- const EMBEDDED_TUPLE_COORD = 0x8000;
4
- const INTERMEDIATE_TUPLE = 0x4000;
5
- const PRIVATE_POINT_NUMBERS = 0x2000;
6
- const TUPLE_INDEX_MASK = 0x0fff;
7
- const POINTS_ARE_WORDS = 0x80;
8
- const POINT_RUN_COUNT_MASK = 0x7f;
9
- const DELTAS_ARE_ZERO = 0x80;
10
- const DELTAS_ARE_WORDS = 0x40;
11
- const DELTA_RUN_COUNT_MASK = 0x3f;
8
+ const TUPLE_COUNT_MASK = 0x0fff;
9
+ const EMBEDDED_TUPLE_COORD = 0x8000;
10
+ const INTERMEDIATE_TUPLE = 0x4000;
11
+ const PRIVATE_POINT_NUMBERS = 0x2000;
12
+ const TUPLE_INDEX_MASK = 0x0fff;
13
+ const POINTS_ARE_WORDS = 0x80;
14
+ const POINT_RUN_COUNT_MASK = 0x7f;
15
+ const DELTAS_ARE_ZERO = 0x80;
16
+ const DELTAS_ARE_WORDS = 0x40;
17
+ const DELTA_RUN_COUNT_MASK = 0x3f;
12
18
 
13
19
  /**
14
20
  * This class is transforms TrueType glyphs according to the data from
@@ -22,18 +28,35 @@ const DELTA_RUN_COUNT_MASK = 0x3f;
22
28
  * @private
23
29
  */
24
30
  export default class GlyphVariationProcessor {
31
+ /**
32
+ * @param {FontLike} font
33
+ * @param {number[]} coords
34
+ */
25
35
  constructor(font, coords) {
36
+ /** @type {FontLike} */
26
37
  this.font = font;
38
+ /** @type {number[]} */
27
39
  this.normalizedCoords = this.normalizeCoords(coords);
28
- this.blendVectors = new Map;
40
+ /** @type {Map<ItemVariationData, number[]>} */
41
+ this.blendVectors = new Map();
29
42
  }
30
43
 
44
+ /**
45
+ * @param {number[]} coords
46
+ * @returns {number[]}
47
+ */
31
48
  normalizeCoords(coords) {
32
49
  // the default mapping is linear along each axis, in two segments:
33
50
  // from the minValue to defaultValue, and from defaultValue to maxValue.
51
+ /** @type {number[]} */
34
52
  let normalized = [];
35
- for (let i = 0; i < this.font.fvar.axis.length; i++) {
36
- let axis = this.font.fvar.axis[i];
53
+ let fvar = this.font.fvar;
54
+ if (!fvar) {
55
+ return normalized;
56
+ }
57
+
58
+ for (let i = 0; i < fvar.axis.length; i++) {
59
+ let axis = fvar.axis[i];
37
60
  if (coords[i] < axis.defaultValue) {
38
61
  normalized.push((coords[i] - axis.defaultValue + Number.EPSILON) / (axis.defaultValue - axis.minValue + Number.EPSILON));
39
62
  } else {
@@ -50,9 +73,9 @@ export default class GlyphVariationProcessor {
50
73
  let pair = segment.correspondence[j];
51
74
  if (j >= 1 && normalized[i] < pair.fromCoord) {
52
75
  let prev = segment.correspondence[j - 1];
53
- normalized[i] = ((normalized[i] - prev.fromCoord) * (pair.toCoord - prev.toCoord) + Number.EPSILON) /
54
- (pair.fromCoord - prev.fromCoord + Number.EPSILON) +
55
- prev.toCoord;
76
+ normalized[i] = ((normalized[i] - prev.fromCoord) * (pair.toCoord - prev.toCoord) + Number.EPSILON)
77
+ / (pair.fromCoord - prev.fromCoord + Number.EPSILON)
78
+ + prev.toCoord;
56
79
 
57
80
  break;
58
81
  }
@@ -63,6 +86,11 @@ export default class GlyphVariationProcessor {
63
86
  return normalized;
64
87
  }
65
88
 
89
+ /**
90
+ * @param {number} gid
91
+ * @param {GlyphPoint[]} glyphPoints
92
+ * @returns {void}
93
+ */
66
94
  transformPoints(gid, glyphPoints) {
67
95
  if (!this.font.fvar || !this.font.gvar) { return; }
68
96
 
@@ -82,10 +110,12 @@ export default class GlyphVariationProcessor {
82
110
  let tupleCount = stream.readUInt16BE();
83
111
  let offsetToData = offset + stream.readUInt16BE();
84
112
 
113
+ /** @type {Uint16Array} */
114
+ let sharedPoints = new Uint16Array(0);
85
115
  if (tupleCount & TUPLES_SHARE_POINT_NUMBERS) {
86
116
  let here = stream.pos;
87
117
  stream.pos = offsetToData;
88
- var sharedPoints = this.decodePoints();
118
+ sharedPoints = this.decodePoints();
89
119
  offsetToData = stream.pos;
90
120
  stream.pos = here;
91
121
  }
@@ -97,13 +127,13 @@ export default class GlyphVariationProcessor {
97
127
  let tupleDataSize = stream.readUInt16BE();
98
128
  let tupleIndex = stream.readUInt16BE();
99
129
 
130
+ /** @type {number[]} */
100
131
  let tupleCoords;
101
132
  if (tupleIndex & EMBEDDED_TUPLE_COORD) {
102
133
  tupleCoords = [];
103
134
  for (let a = 0; a < gvar.axisCount; a++) {
104
135
  tupleCoords.push(stream.readInt16BE() / 16384);
105
136
  }
106
-
107
137
  } else {
108
138
  if ((tupleIndex & TUPLE_INDEX_MASK) >= gvar.globalCoordCount) {
109
139
  throw new Error('Invalid gvar table');
@@ -112,13 +142,17 @@ export default class GlyphVariationProcessor {
112
142
  tupleCoords = gvar.globalCoords[tupleIndex & TUPLE_INDEX_MASK];
113
143
  }
114
144
 
145
+ /** @type {number[] | undefined} */
146
+ let startCoords;
147
+ /** @type {number[] | undefined} */
148
+ let endCoords;
115
149
  if (tupleIndex & INTERMEDIATE_TUPLE) {
116
- var startCoords = [];
150
+ startCoords = [];
117
151
  for (let a = 0; a < gvar.axisCount; a++) {
118
152
  startCoords.push(stream.readInt16BE() / 16384);
119
153
  }
120
154
 
121
- var endCoords = [];
155
+ endCoords = [];
122
156
  for (let a = 0; a < gvar.axisCount; a++) {
123
157
  endCoords.push(stream.readInt16BE() / 16384);
124
158
  }
@@ -134,6 +168,7 @@ export default class GlyphVariationProcessor {
134
168
  let here = stream.pos;
135
169
  stream.pos = offsetToData;
136
170
 
171
+ /** @type {Uint16Array} */
137
172
  let points;
138
173
  if (tupleIndex & PRIVATE_POINT_NUMBERS) {
139
174
  points = this.decodePoints();
@@ -147,34 +182,34 @@ export default class GlyphVariationProcessor {
147
182
  let yDeltas = this.decodeDeltas(nPoints);
148
183
 
149
184
  if (points.length === 0) { // all points
150
- for (let i = 0; i < glyphPoints.length; i++) {
151
- var point = glyphPoints[i];
152
- point.x += Math.round(xDeltas[i] * factor);
153
- point.y += Math.round(yDeltas[i] * factor);
185
+ for (let pi = 0; pi < glyphPoints.length; pi++) {
186
+ let point = glyphPoints[pi];
187
+ point.x += Math.round(xDeltas[pi] * factor);
188
+ point.y += Math.round(yDeltas[pi] * factor);
154
189
  }
155
190
  } else {
156
191
  let outPoints = origPoints.map(pt => pt.copy());
157
192
  let hasDelta = glyphPoints.map(() => false);
158
193
 
159
- for (let i = 0; i < points.length; i++) {
160
- let idx = points[i];
194
+ for (let pi = 0; pi < points.length; pi++) {
195
+ let idx = points[pi];
161
196
  if (idx < glyphPoints.length) {
162
197
  let point = outPoints[idx];
163
198
  hasDelta[idx] = true;
164
199
 
165
- point.x += xDeltas[i] * factor;
166
- point.y += yDeltas[i] * factor;
200
+ point.x += xDeltas[pi] * factor;
201
+ point.y += yDeltas[pi] * factor;
167
202
  }
168
203
  }
169
204
 
170
205
  this.interpolateMissingDeltas(outPoints, origPoints, hasDelta);
171
206
 
172
- for (let i = 0; i < glyphPoints.length; i++) {
173
- let deltaX = outPoints[i].x - origPoints[i].x;
174
- let deltaY = outPoints[i].y - origPoints[i].y;
207
+ for (let pi = 0; pi < glyphPoints.length; pi++) {
208
+ let deltaX = outPoints[pi].x - origPoints[pi].x;
209
+ let deltaY = outPoints[pi].y - origPoints[pi].y;
175
210
 
176
- glyphPoints[i].x = Math.round(glyphPoints[i].x + deltaX);
177
- glyphPoints[i].y = Math.round(glyphPoints[i].y + deltaY);
211
+ glyphPoints[pi].x = Math.round(glyphPoints[pi].x + deltaX);
212
+ glyphPoints[pi].y = Math.round(glyphPoints[pi].y + deltaY);
178
213
  }
179
214
  }
180
215
 
@@ -183,6 +218,9 @@ export default class GlyphVariationProcessor {
183
218
  }
184
219
  }
185
220
 
221
+ /**
222
+ * @returns {Uint16Array}
223
+ */
186
224
  decodePoints() {
187
225
  let stream = this.font.stream;
188
226
  let count = stream.readUInt8();
@@ -197,7 +235,8 @@ export default class GlyphVariationProcessor {
197
235
  while (i < count) {
198
236
  let run = stream.readUInt8();
199
237
  let runCount = (run & POINT_RUN_COUNT_MASK) + 1;
200
- let fn = run & POINTS_ARE_WORDS ? stream.readUInt16 : stream.readUInt8;
238
+ // gvar point numbers are big-endian (OpenType); was incorrectly readUInt16.
239
+ let fn = run & POINTS_ARE_WORDS ? stream.readUInt16BE : stream.readUInt8;
201
240
 
202
241
  for (let j = 0; j < runCount && i < count; j++) {
203
242
  point += fn.call(stream);
@@ -208,6 +247,10 @@ export default class GlyphVariationProcessor {
208
247
  return points;
209
248
  }
210
249
 
250
+ /**
251
+ * @param {number} count
252
+ * @returns {Int16Array}
253
+ */
211
254
  decodeDeltas(count) {
212
255
  let stream = this.font.stream;
213
256
  let i = 0;
@@ -219,7 +262,6 @@ export default class GlyphVariationProcessor {
219
262
 
220
263
  if (run & DELTAS_ARE_ZERO) {
221
264
  i += runCount;
222
-
223
265
  } else {
224
266
  let fn = run & DELTAS_ARE_WORDS ? stream.readInt16BE : stream.readInt8;
225
267
  for (let j = 0; j < runCount && i < count; j++) {
@@ -231,9 +273,19 @@ export default class GlyphVariationProcessor {
231
273
  return deltas;
232
274
  }
233
275
 
276
+ /**
277
+ * @param {number} tupleIndex
278
+ * @param {number[]} tupleCoords
279
+ * @param {number[] | undefined} startCoords
280
+ * @param {number[] | undefined} endCoords
281
+ * @returns {number}
282
+ */
234
283
  tupleFactor(tupleIndex, tupleCoords, startCoords, endCoords) {
235
284
  let normalized = this.normalizedCoords;
236
285
  let { gvar } = this.font;
286
+ if (!gvar) {
287
+ return 0;
288
+ }
237
289
  let factor = 1;
238
290
 
239
291
  for (let i = 0; i < gvar.axisCount; i++) {
@@ -246,20 +298,21 @@ export default class GlyphVariationProcessor {
246
298
  }
247
299
 
248
300
  if ((tupleIndex & INTERMEDIATE_TUPLE) === 0) {
249
- if ((normalized[i] < Math.min(0, tupleCoords[i])) ||
250
- (normalized[i] > Math.max(0, tupleCoords[i]))) {
301
+ if ((normalized[i] < Math.min(0, tupleCoords[i]))
302
+ || (normalized[i] > Math.max(0, tupleCoords[i]))) {
251
303
  return 0;
252
304
  }
253
305
 
254
306
  factor = (factor * normalized[i] + Number.EPSILON) / (tupleCoords[i] + Number.EPSILON);
255
307
  } else {
256
- if ((normalized[i] < startCoords[i]) ||
257
- (normalized[i] > endCoords[i])) {
308
+ if (!startCoords || !endCoords) {
309
+ return 0;
310
+ }
311
+ if ((normalized[i] < startCoords[i])
312
+ || (normalized[i] > endCoords[i])) {
258
313
  return 0;
259
-
260
314
  } else if (normalized[i] < tupleCoords[i]) {
261
315
  factor = factor * (normalized[i] - startCoords[i] + Number.EPSILON) / (tupleCoords[i] - startCoords[i] + Number.EPSILON);
262
-
263
316
  } else {
264
317
  factor = factor * (endCoords[i] - normalized[i] + Number.EPSILON) / (endCoords[i] - tupleCoords[i] + Number.EPSILON);
265
318
  }
@@ -269,9 +322,15 @@ export default class GlyphVariationProcessor {
269
322
  return factor;
270
323
  }
271
324
 
272
- // Interpolates points without delta values.
273
- // Needed for the Ø and Q glyphs in Skia.
274
- // Algorithm from Freetype.
325
+ /**
326
+ * Interpolates points without delta values.
327
+ * Needed for the Ø and Q glyphs in Skia.
328
+ * Algorithm from Freetype.
329
+ * @param {GlyphPoint[]} points
330
+ * @param {GlyphPoint[]} inPoints
331
+ * @param {boolean[]} hasDelta
332
+ * @returns {void}
333
+ */
275
334
  interpolateMissingDeltas(points, inPoints, hasDelta) {
276
335
  if (points.length === 0) {
277
336
  return;
@@ -327,24 +386,36 @@ export default class GlyphVariationProcessor {
327
386
  }
328
387
  }
329
388
 
389
+ /**
390
+ * @param {number} p1
391
+ * @param {number} p2
392
+ * @param {number} ref1
393
+ * @param {number} ref2
394
+ * @param {GlyphPoint[]} inPoints
395
+ * @param {GlyphPoint[]} outPoints
396
+ * @returns {void}
397
+ */
330
398
  deltaInterpolate(p1, p2, ref1, ref2, inPoints, outPoints) {
331
399
  if (p1 > p2) {
332
400
  return;
333
401
  }
334
402
 
403
+ /** @type {Array<'x' | 'y'>} */
335
404
  let iterable = ['x', 'y'];
336
405
  for (let i = 0; i < iterable.length; i++) {
337
406
  let k = iterable[i];
338
- if (inPoints[ref1][k] > inPoints[ref2][k]) {
339
- var p = ref1;
340
- ref1 = ref2;
341
- ref2 = p;
407
+ let r1 = ref1;
408
+ let r2 = ref2;
409
+ if (inPoints[r1][k] > inPoints[r2][k]) {
410
+ let p = r1;
411
+ r1 = r2;
412
+ r2 = p;
342
413
  }
343
414
 
344
- let in1 = inPoints[ref1][k];
345
- let in2 = inPoints[ref2][k];
346
- let out1 = outPoints[ref1][k];
347
- let out2 = outPoints[ref2][k];
415
+ let in1 = inPoints[r1][k];
416
+ let in2 = inPoints[r2][k];
417
+ let out1 = outPoints[r1][k];
418
+ let out2 = outPoints[r2][k];
348
419
 
349
420
  // If the reference points have the same coordinate but different
350
421
  // delta, inferred delta is zero. Otherwise interpolate.
@@ -368,6 +439,14 @@ export default class GlyphVariationProcessor {
368
439
  }
369
440
  }
370
441
 
442
+ /**
443
+ * @param {number} p1
444
+ * @param {number} p2
445
+ * @param {number} ref
446
+ * @param {GlyphPoint[]} inPoints
447
+ * @param {GlyphPoint[]} outPoints
448
+ * @returns {void}
449
+ */
371
450
  deltaShift(p1, p2, ref, inPoints, outPoints) {
372
451
  let deltaX = outPoints[ref].x - inPoints[ref].x;
373
452
  let deltaY = outPoints[ref].y - inPoints[ref].y;
@@ -384,6 +463,11 @@ export default class GlyphVariationProcessor {
384
463
  }
385
464
  }
386
465
 
466
+ /**
467
+ * @param {number} gid
468
+ * @param {HVARTable} table
469
+ * @returns {number}
470
+ */
387
471
  getAdvanceAdjustment(gid, table) {
388
472
  let outerIndex, innerIndex;
389
473
 
@@ -393,7 +477,7 @@ export default class GlyphVariationProcessor {
393
477
  idx = table.advanceWidthMapping.mapCount - 1;
394
478
  }
395
479
 
396
- ({outerIndex, innerIndex} = table.advanceWidthMapping.mapData[idx]);
480
+ ({ outerIndex, innerIndex } = table.advanceWidthMapping.mapData[idx]);
397
481
  } else {
398
482
  outerIndex = 0;
399
483
  innerIndex = gid;
@@ -402,8 +486,14 @@ export default class GlyphVariationProcessor {
402
486
  return this.getDelta(table.itemVariationStore, outerIndex, innerIndex);
403
487
  }
404
488
 
405
- // See pseudo code from `Font Variations Overview'
406
- // in the OpenType specification.
489
+ /**
490
+ * See pseudo code from `Font Variations Overview'
491
+ * in the OpenType specification.
492
+ * @param {ItemVariationStore} itemStore
493
+ * @param {number} outerIndex
494
+ * @param {number} innerIndex
495
+ * @returns {number}
496
+ */
407
497
  getDelta(itemStore, outerIndex, innerIndex) {
408
498
  if (outerIndex >= itemStore.itemVariationData.length) {
409
499
  return 0;
@@ -425,13 +515,20 @@ export default class GlyphVariationProcessor {
425
515
  return netAdjustment;
426
516
  }
427
517
 
518
+ /**
519
+ * @param {ItemVariationStore} itemStore
520
+ * @param {number} outerIndex
521
+ * @returns {number[]}
522
+ */
428
523
  getBlendVector(itemStore, outerIndex) {
429
524
  let varData = itemStore.itemVariationData[outerIndex];
430
- if (this.blendVectors.has(varData)) {
431
- return this.blendVectors.get(varData);
525
+ let cached = this.blendVectors.get(varData);
526
+ if (cached) {
527
+ return cached;
432
528
  }
433
529
 
434
530
  let normalizedCoords = this.normalizedCoords;
531
+ /** @type {number[]} */
435
532
  let blendVector = [];
436
533
 
437
534
  // outer loop steps through master designs to be blended
@@ -449,7 +546,6 @@ export default class GlyphVariationProcessor {
449
546
  // ignore invalid ranges
450
547
  if (axis.startCoord > axis.peakCoord || axis.peakCoord > axis.endCoord) {
451
548
  axisScalar = 1;
452
-
453
549
  } else if (axis.startCoord < 0 && axis.endCoord > 0 && axis.peakCoord !== 0) {
454
550
  axisScalar = 1;
455
551
 
@@ -466,11 +562,11 @@ export default class GlyphVariationProcessor {
466
562
  if (normalizedCoords[j] === axis.peakCoord) {
467
563
  axisScalar = 1;
468
564
  } else if (normalizedCoords[j] < axis.peakCoord) {
469
- axisScalar = (normalizedCoords[j] - axis.startCoord + Number.EPSILON) /
470
- (axis.peakCoord - axis.startCoord + Number.EPSILON);
565
+ axisScalar = (normalizedCoords[j] - axis.startCoord + Number.EPSILON)
566
+ / (axis.peakCoord - axis.startCoord + Number.EPSILON);
471
567
  } else {
472
- axisScalar = (axis.endCoord - normalizedCoords[j] + Number.EPSILON) /
473
- (axis.endCoord - axis.peakCoord + Number.EPSILON);
568
+ axisScalar = (axis.endCoord - normalizedCoords[j] + Number.EPSILON)
569
+ / (axis.endCoord - axis.peakCoord + Number.EPSILON);
474
570
  }
475
571
  }
476
572