@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,9 +1,19 @@
1
1
  import Glyph from './Glyph';
2
2
  import BBox from './BBox';
3
3
 
4
+ /** @typedef {import('../../types/fontkit').CPALColor} CPALColor */
5
+ /** @typedef {import('../../types/fontkit').GlyphLike} GlyphLike */
6
+ /** @typedef {import('../../types/fontkit').PathRenderingContext} PathRenderingContext */
7
+
4
8
  class COLRLayer {
9
+ /**
10
+ * @param {GlyphLike | null | undefined} glyph
11
+ * @param {CPALColor} color
12
+ */
5
13
  constructor(glyph, color) {
14
+ /** @type {GlyphLike | null | undefined} */
6
15
  this.glyph = glyph;
16
+ /** @type {CPALColor} */
7
17
  this.color = color;
8
18
  }
9
19
  }
@@ -16,16 +26,22 @@ class COLRLayer {
16
26
  export default class COLRGlyph extends Glyph {
17
27
  type = 'COLR';
18
28
 
29
+ /**
30
+ * @returns {BBox}
31
+ */
19
32
  _getBBox() {
20
33
  let layers = this.layers;
21
34
  if (!layers) {
22
35
  let g = this._font._getBaseGlyph(this.id);
23
- return g ? g.bbox : new BBox(0, 0, 0, 0);
36
+ return g ? new BBox(g.bbox.minX, g.bbox.minY, g.bbox.maxX, g.bbox.maxY) : new BBox(0, 0, 0, 0);
24
37
  }
25
38
 
26
- let bbox = new BBox;
39
+ let bbox = new BBox();
27
40
  for (let i = 0; i < layers.length; i++) {
28
41
  let layer = layers[i];
42
+ if (!layer.glyph) {
43
+ continue;
44
+ }
29
45
  let b = layer.glyph.bbox;
30
46
  bbox.addPoint(b.minX, b.minY);
31
47
  bbox.addPoint(b.maxX, b.maxY);
@@ -37,7 +53,7 @@ export default class COLRGlyph extends Glyph {
37
53
  /**
38
54
  * Returns an array of objects containing the glyph and color for
39
55
  * each layer in the composite color glyph.
40
- * @type {object[]}
56
+ * @type {COLRLayer[] | null}
41
57
  */
42
58
  get layers() {
43
59
  let cpal = this._font.CPAL;
@@ -50,6 +66,7 @@ export default class COLRGlyph extends Glyph {
50
66
 
51
67
  let low = 0;
52
68
  let high = colr.baseGlyphRecord.length - 1;
69
+ /** @type {import('../../types/fontkit').COLRBaseGlyphRecord | undefined} */
53
70
  let baseLayer;
54
71
 
55
72
  while (low <= high) {
@@ -70,6 +87,7 @@ export default class COLRGlyph extends Glyph {
70
87
  // default to normal glyph from glyf or CFF
71
88
  if (baseLayer == null) {
72
89
  let g = this._font._getBaseGlyph(this.id);
90
+ /** @type {CPALColor} */
73
91
  let color = {
74
92
  red: 0,
75
93
  green: 0,
@@ -81,10 +99,17 @@ export default class COLRGlyph extends Glyph {
81
99
  }
82
100
 
83
101
  // otherwise, return an array of all the layers
102
+ /** @type {COLRLayer[]} */
84
103
  let layers = [];
85
104
  for (let i = baseLayer.firstLayerIndex; i < baseLayer.firstLayerIndex + baseLayer.numLayers; i++) {
86
105
  let rec = colr.layerRecords[i];
106
+ if (!cpal || !rec) {
107
+ continue;
108
+ }
87
109
  let color = cpal.colorRecords[rec.paletteIndex];
110
+ if (!color) {
111
+ continue;
112
+ }
88
113
  let g = this._font._getBaseGlyph(rec.gid);
89
114
  layers.push(new COLRLayer(g, color));
90
115
  }
@@ -92,14 +117,24 @@ export default class COLRGlyph extends Glyph {
92
117
  return layers;
93
118
  }
94
119
 
120
+ /**
121
+ * @param {PathRenderingContext} ctx
122
+ * @param {number} size
123
+ * @returns {void}
124
+ */
95
125
  render(ctx, size) {
96
126
  let layers = this.layers;
97
127
  if (!layers) {
98
128
  return;
99
129
  }
100
130
 
101
- for (let {glyph, color} of layers) {
102
- ctx.fillColor([color.red, color.green, color.blue], color.alpha / 255 * 100);
131
+ for (let { glyph, color } of layers) {
132
+ if (!glyph) {
133
+ continue;
134
+ }
135
+ if (typeof ctx.fillColor === 'function') {
136
+ ctx.fillColor([color.red, color.green, color.blue], color.alpha / 255 * 100);
137
+ }
103
138
  glyph.render(ctx, size);
104
139
  }
105
140
 
@@ -1,8 +1,14 @@
1
1
  import { cache } from '../decorators';
2
2
  import Path from './Path';
3
- import {isMark} from '../packages/unicode-properties/index.js';
3
+ import { isMark } from '../packages/unicode-properties/index.js';
4
4
  import StandardNames from './StandardNames';
5
5
 
6
+ /** @typedef {import('../../types/fontkit').FontLike} FontLike */
7
+ /** @typedef {import('../../types/fontkit').GlyphMetrics} GlyphMetrics */
8
+ /** @typedef {import('../../types/fontkit').MetricsTable} MetricsTable */
9
+ /** @typedef {import('../../types/fontkit').PathRenderingContext} PathRenderingContext */
10
+ /** @typedef {import('./BBox').default} BBox */
11
+
6
12
  /**
7
13
  * Glyph objects represent a glyph in the font. They have various properties for accessing metrics and
8
14
  * the actual vector path the glyph represents, and methods for rendering the glyph to a graphics context.
@@ -12,6 +18,11 @@ import StandardNames from './StandardNames';
12
18
  * on the font format, but they all inherit from this class.
13
19
  */
14
20
  export default class Glyph {
21
+ /**
22
+ * @param {number} id
23
+ * @param {number[]} codePoints
24
+ * @param {FontLike} font
25
+ */
15
26
  constructor(id, codePoints, font) {
16
27
  /**
17
28
  * The glyph id in the font
@@ -26,28 +37,50 @@ export default class Glyph {
26
37
  * @type {number[]}
27
38
  */
28
39
  this.codePoints = codePoints;
40
+
41
+ /** @type {FontLike} */
29
42
  this._font = font;
30
43
 
44
+ /** @type {GlyphMetrics | undefined} */
45
+ this._metrics = undefined;
46
+
31
47
  // TODO: get this info from GDEF if available
32
48
  this.isMark = this.codePoints.length > 0 && this.codePoints.every(isMark);
33
49
  this.isLigature = this.codePoints.length > 1;
34
50
  }
35
51
 
52
+ /**
53
+ * @returns {Path}
54
+ */
36
55
  _getPath() {
37
56
  return new Path();
38
57
  }
39
58
 
59
+ /**
60
+ * @returns {BBox}
61
+ */
40
62
  _getCBox() {
41
63
  return this.path.cbox;
42
64
  }
43
65
 
66
+ /**
67
+ * @returns {BBox}
68
+ */
44
69
  _getBBox() {
45
70
  return this.path.bbox;
46
71
  }
47
72
 
73
+ /**
74
+ * @param {MetricsTable} table
75
+ * @returns {{ advance: number, bearing: number }}
76
+ */
48
77
  _getTableMetrics(table) {
49
78
  if (this.id < table.metrics.length) {
50
- return table.metrics.get(this.id);
79
+ let metric = table.metrics.get(this.id);
80
+ return {
81
+ advance: metric ? metric.advance : 0,
82
+ bearing: metric ? metric.bearing : 0
83
+ };
51
84
  }
52
85
 
53
86
  let metric = table.metrics.get(table.metrics.length - 1);
@@ -59,16 +92,20 @@ export default class Glyph {
59
92
  return res;
60
93
  }
61
94
 
95
+ /**
96
+ * @param {BBox} [cbox]
97
+ * @returns {GlyphMetrics}
98
+ */
62
99
  _getMetrics(cbox) {
63
100
  if (this._metrics) { return this._metrics; }
64
101
  if (cbox == null) { ({ cbox } = this); }
65
102
 
66
- let {advance: advanceWidth, bearing: leftBearing} = this._getTableMetrics(this._font.hmtx);
103
+ let { advance: advanceWidth, bearing: leftBearing } = this._getTableMetrics(this._font.hmtx);
67
104
 
68
105
  // Vertical metrics: vmtx, else font ascent/descent (respects useTypoMetrics)
69
106
  let advanceHeight, topBearing;
70
107
  if (this._font.vmtx) {
71
- ({advance: advanceHeight, bearing: topBearing} = this._getTableMetrics(this._font.vmtx));
108
+ ({ advance: advanceHeight, bearing: topBearing } = this._getTableMetrics(this._font.vmtx));
72
109
  } else {
73
110
  advanceHeight = Math.abs(this._font.ascent - this._font.descent);
74
111
  topBearing = this._font.ascent - cbox.maxY;
@@ -78,7 +115,7 @@ export default class Glyph {
78
115
  advanceWidth += this._font._variationProcessor.getAdvanceAdjustment(this.id, this._font.HVAR);
79
116
  }
80
117
 
81
- let {width, height} = cbox;
118
+ let { width, height } = cbox;
82
119
  return this._metrics = {
83
120
  width,
84
121
  height,
@@ -210,10 +247,16 @@ export default class Glyph {
210
247
  return this._getMetrics().bottomBearing;
211
248
  }
212
249
 
250
+ /**
251
+ * @returns {null}
252
+ */
213
253
  get ligatureCaretPositions() {
214
254
  return null;
215
255
  }
216
256
 
257
+ /**
258
+ * @returns {string | null | undefined}
259
+ */
217
260
  _getName() {
218
261
  let { post } = this._font;
219
262
  if (!post) {
@@ -225,25 +268,40 @@ export default class Glyph {
225
268
  return StandardNames[this.id];
226
269
 
227
270
  case 2: {
228
- let id = post.glyphNameIndex[this.id];
271
+ let id = post.glyphNameIndex?.[this.id];
272
+ if (id == null) {
273
+ return null;
274
+ }
229
275
  if (id < StandardNames.length) {
230
276
  return StandardNames[id];
231
277
  }
232
278
 
233
- return post.names[id - StandardNames.length];
279
+ return post.names?.[id - StandardNames.length];
234
280
  }
235
281
 
236
- case 2.5:
237
- return StandardNames[this.id + post.offsets[this.id]];
282
+ case 2.5: {
283
+ let offset = post.offsets?.[this.id];
284
+ if (offset == null) {
285
+ return null;
286
+ }
287
+ return StandardNames[this.id + offset];
288
+ }
238
289
 
239
- case 4:
240
- return String.fromCharCode(post.map[this.id]);
290
+ case 4: {
291
+ let mapped = post.map?.[this.id];
292
+ if (mapped == null) {
293
+ return null;
294
+ }
295
+ return String.fromCharCode(mapped);
296
+ }
241
297
  }
298
+
299
+ return null;
242
300
  }
243
301
 
244
302
  /**
245
303
  * The glyph's name
246
- * @type {string}
304
+ * @type {string | null | undefined}
247
305
  */
248
306
  @cache
249
307
  get name() {
@@ -252,8 +310,9 @@ export default class Glyph {
252
310
 
253
311
  /**
254
312
  * Renders the glyph to the given graphics context, at the specified font size.
255
- * @param {CanvasRenderingContext2d} ctx
313
+ * @param {PathRenderingContext} ctx
256
314
  * @param {number} size
315
+ * @returns {void}
257
316
  */
258
317
  render(ctx, size) {
259
318
  ctx.save();