@cantoo/fontkit 2.0.5 → 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.
- package/dist/browser-module.mjs +4423 -1117
- package/dist/browser-module.mjs.map +1 -1
- package/dist/browser.cjs +4424 -1117
- package/dist/browser.cjs.map +1 -1
- package/dist/main.cjs +4424 -1117
- package/dist/main.cjs.map +1 -1
- package/dist/module.mjs +4423 -1117
- package/dist/module.mjs.map +1 -1
- package/package.json +3 -1
- package/src/CmapProcessor.js +59 -20
- package/src/DFont.js +114 -14
- package/src/TTFFont.js +259 -57
- package/src/TrueTypeCollection.js +54 -10
- package/src/WOFF2Font.js +128 -16
- package/src/WOFFFont.js +45 -8
- package/src/aat/AATFeatureMap.js +62 -18
- package/src/aat/AATLayoutEngine.js +33 -1
- package/src/aat/AATLookupTable.js +22 -4
- package/src/aat/AATMorxProcessor.js +189 -52
- package/src/aat/AATStateMachine.js +32 -0
- package/src/base.js +19 -0
- package/src/cff/CFFCharsets.js +3 -0
- package/src/cff/CFFDict.js +79 -9
- package/src/cff/CFFEncodings.js +2 -0
- package/src/cff/CFFFont.js +119 -23
- package/src/cff/CFFIndex.js +62 -5
- package/src/cff/CFFOperand.js +52 -17
- package/src/cff/CFFPointer.js +41 -2
- package/src/cff/CFFPrivateDict.js +14 -4
- package/src/cff/CFFStandardStrings.js +1 -0
- package/src/cff/CFFTop.js +103 -10
- package/src/decorators.js +32 -13
- package/src/encodings.js +22 -5
- package/src/fs.js +10 -0
- package/src/glyph/BBox.js +14 -0
- package/src/glyph/CFFGlyph.js +290 -148
- package/src/glyph/COLRGlyph.js +38 -3
- package/src/glyph/Glyph.js +68 -9
- package/src/glyph/GlyphVariationProcessor.js +135 -34
- package/src/glyph/Path.js +107 -20
- package/src/glyph/SBIXGlyph.js +57 -8
- package/src/glyph/StandardNames.js +1 -0
- package/src/glyph/TTFGlyph.js +176 -29
- package/src/glyph/TTFGlyphEncoder.js +32 -0
- package/src/glyph/WOFF2Glyph.js +23 -4
- package/src/layout/GlyphPosition.js +6 -0
- package/src/layout/GlyphRun.js +25 -7
- package/src/layout/KernProcessor.js +62 -3
- package/src/layout/LayoutEngine.js +86 -12
- package/src/layout/Script.js +27 -1
- package/src/layout/UnicodeLayoutEngine.js +29 -4
- package/src/opentype/GPOSProcessor.js +156 -45
- package/src/opentype/GSUBProcessor.js +92 -33
- package/src/opentype/GlyphInfo.js +52 -4
- package/src/opentype/GlyphIterator.js +51 -2
- package/src/opentype/OTLayoutEngine.js +66 -8
- package/src/opentype/OTProcessor.js +283 -70
- package/src/opentype/ShapingPlan.js +51 -3
- package/src/opentype/shapers/ArabicShaper.js +19 -0
- package/src/opentype/shapers/DefaultShaper.js +51 -7
- package/src/opentype/shapers/HangulShaper.js +85 -7
- package/src/opentype/shapers/HebrewShaper.js +45 -11
- package/src/opentype/shapers/IndicShaper.js +141 -26
- package/src/opentype/shapers/ThaiShaper.js +35 -4
- package/src/opentype/shapers/UniversalShaper.js +83 -17
- package/src/opentype/shapers/index.js +15 -2
- package/src/packages/unicode-properties/data-trie.js +1 -0
- package/src/packages/unicode-properties/data.js +12 -0
- package/src/packages/unicode-properties/dist/index.cjs +22 -9
- package/src/packages/unicode-properties/dist/index.cjs.map +2 -2
- package/src/packages/unicode-properties/dist/index.mjs +21 -9
- package/src/packages/unicode-properties/dist/index.mjs.map +2 -2
- package/src/packages/unicode-properties/index.js +65 -0
- package/src/packages/unicode-properties/package.json +1 -1
- package/src/packages/unicode-trie/builder.js +128 -7
- package/src/packages/unicode-trie/dist/builder.cjs +129 -16
- package/src/packages/unicode-trie/dist/builder.cjs.map +2 -2
- package/src/packages/unicode-trie/dist/builder.mjs +128 -16
- package/src/packages/unicode-trie/dist/builder.mjs.map +2 -2
- package/src/packages/unicode-trie/dist/index.cjs +22 -9
- package/src/packages/unicode-trie/dist/index.cjs.map +2 -2
- package/src/packages/unicode-trie/dist/index.mjs +21 -9
- package/src/packages/unicode-trie/dist/index.mjs.map +2 -2
- package/src/packages/unicode-trie/index.js +62 -10
- package/src/packages/unicode-trie/package.json +1 -1
- package/src/packages/unicode-trie/swap.js +13 -0
- package/src/subset/CFFSubset.js +112 -22
- package/src/subset/Subset.js +21 -1
- package/src/subset/TTFSubset.js +79 -36
- package/src/tables/BASE.js +1 -0
- package/src/tables/COLR.js +1 -0
- package/src/tables/CPAL.js +1 -0
- package/src/tables/DSIG.js +1 -0
- package/src/tables/EBDT.js +10 -3
- package/src/tables/EBLC.js +67 -7
- package/src/tables/GDEF.js +1 -0
- package/src/tables/GPOS.js +79 -16
- package/src/tables/GSUB.js +14 -3
- package/src/tables/HVAR.js +51 -5
- package/src/tables/JSTF.js +3 -2
- package/src/tables/LTSH.js +1 -0
- package/src/tables/OS2.js +1 -0
- package/src/tables/PCLT.js +1 -0
- package/src/tables/STAT.js +46 -6
- package/src/tables/VDMX.js +1 -0
- package/src/tables/VORG.js +1 -0
- package/src/tables/WOFF2Directory.js +56 -8
- package/src/tables/WOFFDirectory.js +14 -2
- package/src/tables/aat.js +160 -35
- package/src/tables/avar.js +1 -0
- package/src/tables/bsln.js +3 -2
- package/src/tables/cmap.js +26 -6
- package/src/tables/cvt.js +1 -0
- package/src/tables/directory.js +44 -16
- package/src/tables/feat.js +24 -2
- package/src/tables/fpgm.js +1 -0
- package/src/tables/fvar.js +32 -4
- package/src/tables/gasp.js +1 -0
- package/src/tables/glyf.js +1 -0
- package/src/tables/gvar.js +29 -2
- package/src/tables/hdmx.js +12 -1
- package/src/tables/head.js +1 -0
- package/src/tables/hhea.js +1 -0
- package/src/tables/hmtx.js +18 -2
- package/src/tables/index.js +1 -0
- package/src/tables/just.js +15 -4
- package/src/tables/kern.js +43 -6
- package/src/tables/loca.js +21 -8
- package/src/tables/maxp.js +1 -0
- package/src/tables/morx.js +14 -7
- package/src/tables/name.js +104 -23
- package/src/tables/opbd.js +2 -1
- package/src/tables/opentype.js +39 -4
- package/src/tables/post.js +8 -1
- package/src/tables/prep.js +1 -0
- package/src/tables/sbix.js +12 -1
- package/src/tables/variations.js +23 -3
- package/src/tables/vhea.js +1 -0
- package/src/tables/vmtx.js +18 -2
- package/src/utils.js +15 -0
|
@@ -1,36 +1,79 @@
|
|
|
1
1
|
import { isMark } from '../packages/unicode-properties/index.js';
|
|
2
2
|
import OTProcessor from './OTProcessor';
|
|
3
3
|
|
|
4
|
+
/** @typedef {import('../../types/fontkit').LayoutFont} LayoutFont */
|
|
5
|
+
/** @typedef {import('../../types/fontkit').FeatureMap} FeatureMap */
|
|
6
|
+
/** @typedef {import('../../types/fontkit').FeatureInput} FeatureInput */
|
|
7
|
+
/** @typedef {import('../../types/fontkit').ClassDefTable} ClassDefTable */
|
|
8
|
+
|
|
4
9
|
export default class GlyphInfo {
|
|
10
|
+
/**
|
|
11
|
+
* @param {LayoutFont} font
|
|
12
|
+
* @param {number} id
|
|
13
|
+
* @param {number[]} [codePoints]
|
|
14
|
+
* @param {FeatureInput | null | undefined} [features]
|
|
15
|
+
*/
|
|
5
16
|
constructor(font, id, codePoints = [], features) {
|
|
17
|
+
/** @type {LayoutFont} */
|
|
6
18
|
this._font = font;
|
|
19
|
+
/** @type {number[]} */
|
|
7
20
|
this.codePoints = codePoints;
|
|
8
|
-
|
|
21
|
+
/** @type {number} */
|
|
22
|
+
this._id = 0;
|
|
9
23
|
|
|
24
|
+
/** @type {FeatureMap} */
|
|
10
25
|
this.features = {};
|
|
11
26
|
if (Array.isArray(features)) {
|
|
12
27
|
for (let i = 0; i < features.length; i++) {
|
|
13
28
|
let feature = features[i];
|
|
14
29
|
this.features[feature] = true;
|
|
15
30
|
}
|
|
16
|
-
} else if (typeof features === 'object') {
|
|
31
|
+
} else if (typeof features === 'object' && features !== null) {
|
|
17
32
|
Object.assign(this.features, features);
|
|
18
33
|
}
|
|
19
34
|
|
|
35
|
+
/** @type {number | null} */
|
|
20
36
|
this.ligatureID = null;
|
|
37
|
+
/** @type {number | null} */
|
|
21
38
|
this.ligatureComponent = null;
|
|
39
|
+
/** @type {boolean} */
|
|
22
40
|
this.isLigated = false;
|
|
41
|
+
/** @type {number | null} */
|
|
23
42
|
this.cursiveAttachment = null;
|
|
43
|
+
/** @type {number | null} */
|
|
24
44
|
this.markAttachment = null;
|
|
45
|
+
/** @type {import('../../types/fontkit').IndicShaperInfo | import('../../types/fontkit').USEShaperInfo | null} */
|
|
25
46
|
this.shaperInfo = null;
|
|
47
|
+
/** @type {boolean} */
|
|
26
48
|
this.substituted = false;
|
|
49
|
+
/** @type {boolean} */
|
|
27
50
|
this.isMultiplied = false;
|
|
51
|
+
|
|
52
|
+
/** @type {boolean} */
|
|
53
|
+
this.isBase = false;
|
|
54
|
+
/** @type {boolean} */
|
|
55
|
+
this.isLigature = false;
|
|
56
|
+
/** @type {boolean} */
|
|
57
|
+
this.isMark = false;
|
|
58
|
+
/** @type {number} */
|
|
59
|
+
this.markAttachmentType = 0;
|
|
60
|
+
|
|
61
|
+
// Apply GDEF / mark classification via the id setter, then clear
|
|
62
|
+
// `substituted` — construction is not a GSUB substitution.
|
|
63
|
+
this.id = id;
|
|
64
|
+
this.substituted = false;
|
|
28
65
|
}
|
|
29
66
|
|
|
67
|
+
/**
|
|
68
|
+
* @returns {number}
|
|
69
|
+
*/
|
|
30
70
|
get id() {
|
|
31
71
|
return this._id;
|
|
32
72
|
}
|
|
33
73
|
|
|
74
|
+
/**
|
|
75
|
+
* @param {number} id
|
|
76
|
+
*/
|
|
34
77
|
set id(id) {
|
|
35
78
|
this._id = id;
|
|
36
79
|
this.substituted = true;
|
|
@@ -38,11 +81,13 @@ export default class GlyphInfo {
|
|
|
38
81
|
let GDEF = this._font.GDEF;
|
|
39
82
|
if (GDEF && GDEF.glyphClassDef) {
|
|
40
83
|
// TODO: clean this up
|
|
41
|
-
let classID = OTProcessor.prototype.getClassID(id, GDEF.glyphClassDef);
|
|
84
|
+
let classID = OTProcessor.prototype.getClassID(id, /** @type {ClassDefTable} */ (GDEF.glyphClassDef));
|
|
42
85
|
this.isBase = classID === 1;
|
|
43
86
|
this.isLigature = classID === 2;
|
|
44
87
|
this.isMark = classID === 3;
|
|
45
|
-
this.markAttachmentType = GDEF.markAttachClassDef
|
|
88
|
+
this.markAttachmentType = GDEF.markAttachClassDef
|
|
89
|
+
? OTProcessor.prototype.getClassID(id, /** @type {ClassDefTable} */ (GDEF.markAttachClassDef))
|
|
90
|
+
: 0;
|
|
46
91
|
} else {
|
|
47
92
|
this.isMark = this.codePoints.length > 0 && this.codePoints.every(isMark);
|
|
48
93
|
this.isBase = !this.isMark;
|
|
@@ -51,6 +96,9 @@ export default class GlyphInfo {
|
|
|
51
96
|
}
|
|
52
97
|
}
|
|
53
98
|
|
|
99
|
+
/**
|
|
100
|
+
* @returns {GlyphInfo}
|
|
101
|
+
*/
|
|
54
102
|
copy() {
|
|
55
103
|
return new GlyphInfo(this._font, this.id, this.codePoints, this.features);
|
|
56
104
|
}
|
|
@@ -1,21 +1,48 @@
|
|
|
1
|
+
/** @typedef {import('../../types/fontkit').GlyphInfoLike} GlyphInfoLike */
|
|
2
|
+
/** @typedef {import('../../types/fontkit').GlyphIteratorOptions} GlyphIteratorOptions */
|
|
3
|
+
/** @typedef {import('../../types/fontkit').LookupFlags} LookupFlags */
|
|
4
|
+
/** @typedef {import('../../types/fontkit').MarkFilteringSet} MarkFilteringSet */
|
|
5
|
+
|
|
1
6
|
export default class GlyphIterator {
|
|
7
|
+
/**
|
|
8
|
+
* @param {GlyphInfoLike[]} glyphs
|
|
9
|
+
* @param {GlyphIteratorOptions} [options]
|
|
10
|
+
*/
|
|
2
11
|
constructor(glyphs, options) {
|
|
12
|
+
/** @type {GlyphInfoLike[]} */
|
|
3
13
|
this.glyphs = glyphs;
|
|
4
14
|
this.reset(options);
|
|
5
15
|
}
|
|
6
16
|
|
|
17
|
+
/**
|
|
18
|
+
* @param {GlyphIteratorOptions} [options]
|
|
19
|
+
* @param {number} [index]
|
|
20
|
+
* @param {MarkFilteringSet | null} [markFilteringSet]
|
|
21
|
+
*/
|
|
7
22
|
reset(options = {}, index = 0, markFilteringSet = null) {
|
|
23
|
+
/** @type {GlyphIteratorOptions} */
|
|
8
24
|
this.options = options;
|
|
25
|
+
/** @type {LookupFlags} */
|
|
9
26
|
this.flags = options.flags || {};
|
|
27
|
+
/** @type {number} */
|
|
10
28
|
this.markAttachmentType = options.markAttachmentType || 0;
|
|
29
|
+
/** @type {MarkFilteringSet | null} */
|
|
11
30
|
this.markFilteringSet = markFilteringSet;
|
|
31
|
+
/** @type {number} */
|
|
12
32
|
this.index = index;
|
|
13
33
|
}
|
|
14
34
|
|
|
35
|
+
/**
|
|
36
|
+
* @returns {GlyphInfoLike | null}
|
|
37
|
+
*/
|
|
15
38
|
get cur() {
|
|
16
39
|
return this.glyphs[this.index] || null;
|
|
17
40
|
}
|
|
18
41
|
|
|
42
|
+
/**
|
|
43
|
+
* @param {GlyphInfoLike} glyph
|
|
44
|
+
* @returns {boolean}
|
|
45
|
+
*/
|
|
19
46
|
shouldIgnore(glyph) {
|
|
20
47
|
// Mark skip hierarchy (OT chapter 2): ignoreMarks > mark filtering set > markAttachmentType.
|
|
21
48
|
if (glyph.isMark) {
|
|
@@ -30,10 +57,14 @@ export default class GlyphIterator {
|
|
|
30
57
|
}
|
|
31
58
|
}
|
|
32
59
|
|
|
33
|
-
return (this.flags.ignoreBaseGlyphs && glyph.isBase)
|
|
34
|
-
|| (this.flags.ignoreLigatures && glyph.isLigature);
|
|
60
|
+
return !!(this.flags.ignoreBaseGlyphs && glyph.isBase)
|
|
61
|
+
|| !!(this.flags.ignoreLigatures && glyph.isLigature);
|
|
35
62
|
}
|
|
36
63
|
|
|
64
|
+
/**
|
|
65
|
+
* @param {number} dir
|
|
66
|
+
* @returns {GlyphInfoLike | null}
|
|
67
|
+
*/
|
|
37
68
|
move(dir) {
|
|
38
69
|
this.index += dir;
|
|
39
70
|
while (0 <= this.index && this.index < this.glyphs.length && this.shouldIgnore(this.glyphs[this.index])) {
|
|
@@ -47,14 +78,24 @@ export default class GlyphIterator {
|
|
|
47
78
|
return this.glyphs[this.index];
|
|
48
79
|
}
|
|
49
80
|
|
|
81
|
+
/**
|
|
82
|
+
* @returns {GlyphInfoLike | null}
|
|
83
|
+
*/
|
|
50
84
|
next() {
|
|
51
85
|
return this.move(+1);
|
|
52
86
|
}
|
|
53
87
|
|
|
88
|
+
/**
|
|
89
|
+
* @returns {GlyphInfoLike | null}
|
|
90
|
+
*/
|
|
54
91
|
prev() {
|
|
55
92
|
return this.move(-1);
|
|
56
93
|
}
|
|
57
94
|
|
|
95
|
+
/**
|
|
96
|
+
* @param {number} [count]
|
|
97
|
+
* @returns {GlyphInfoLike | undefined}
|
|
98
|
+
*/
|
|
58
99
|
peek(count = 1) {
|
|
59
100
|
let idx = this.index;
|
|
60
101
|
let res = this.increment(count);
|
|
@@ -62,6 +103,10 @@ export default class GlyphIterator {
|
|
|
62
103
|
return res;
|
|
63
104
|
}
|
|
64
105
|
|
|
106
|
+
/**
|
|
107
|
+
* @param {number} [count]
|
|
108
|
+
* @returns {number}
|
|
109
|
+
*/
|
|
65
110
|
peekIndex(count = 1) {
|
|
66
111
|
let idx = this.index;
|
|
67
112
|
this.increment(count);
|
|
@@ -70,6 +115,10 @@ export default class GlyphIterator {
|
|
|
70
115
|
return res;
|
|
71
116
|
}
|
|
72
117
|
|
|
118
|
+
/**
|
|
119
|
+
* @param {number} [count]
|
|
120
|
+
* @returns {GlyphInfoLike | undefined}
|
|
121
|
+
*/
|
|
73
122
|
increment(count = 1) {
|
|
74
123
|
let dir = count < 0 ? -1 : 1;
|
|
75
124
|
count = Math.abs(count);
|
|
@@ -4,14 +4,35 @@ import GlyphInfo from './GlyphInfo';
|
|
|
4
4
|
import GSUBProcessor from './GSUBProcessor';
|
|
5
5
|
import GPOSProcessor from './GPOSProcessor';
|
|
6
6
|
|
|
7
|
+
/** @typedef {import('../../types/fontkit').LayoutFont} LayoutFont */
|
|
8
|
+
/** @typedef {import('../../types/fontkit').GlyphRunLike} GlyphRunLike */
|
|
9
|
+
/** @typedef {import('../../types/fontkit').GlyphInfoLike} GlyphInfoLike */
|
|
10
|
+
/** @typedef {import('../../types/fontkit').GlyphPositionLike} GlyphPositionLike */
|
|
11
|
+
/** @typedef {import('../../types/fontkit').FeatureMap} FeatureMap */
|
|
12
|
+
/** @typedef {import('../../types/fontkit').ScriptTag} ScriptTag */
|
|
13
|
+
/** @typedef {import('../../types/fontkit').LanguageTag} LanguageTag */
|
|
14
|
+
/** @typedef {import('../../types/fontkit').LayoutGlyph} LayoutGlyph */
|
|
15
|
+
/** @typedef {import('../../types/fontkit').ShaperLike} ShaperLike */
|
|
16
|
+
|
|
7
17
|
export default class OTLayoutEngine {
|
|
18
|
+
/**
|
|
19
|
+
* @param {LayoutFont} font
|
|
20
|
+
*/
|
|
8
21
|
constructor(font) {
|
|
22
|
+
/** @type {LayoutFont} */
|
|
9
23
|
this.font = font;
|
|
24
|
+
/** @type {GlyphInfo[] | null} */
|
|
10
25
|
this.glyphInfos = null;
|
|
26
|
+
/** @type {ShapingPlan | null} */
|
|
11
27
|
this.plan = null;
|
|
28
|
+
/** @type {GSUBProcessor | null} */
|
|
12
29
|
this.GSUBProcessor = null;
|
|
30
|
+
/** @type {GPOSProcessor | null} */
|
|
13
31
|
this.GPOSProcessor = null;
|
|
32
|
+
/** @type {boolean} */
|
|
14
33
|
this.fallbackPosition = true;
|
|
34
|
+
/** @type {ShaperLike | null} */
|
|
35
|
+
this.shaper = null;
|
|
15
36
|
|
|
16
37
|
if (font.GSUB) {
|
|
17
38
|
this.GSUBProcessor = new GSUBProcessor(font, font.GSUB);
|
|
@@ -22,12 +43,18 @@ export default class OTLayoutEngine {
|
|
|
22
43
|
}
|
|
23
44
|
}
|
|
24
45
|
|
|
46
|
+
/**
|
|
47
|
+
* @param {GlyphRunLike} glyphRun
|
|
48
|
+
*/
|
|
25
49
|
setup(glyphRun) {
|
|
26
50
|
// Map glyphs to GlyphInfo objects so data can be passed between
|
|
27
51
|
// GSUB and GPOS without mutating the real (shared) Glyph objects.
|
|
28
|
-
this.glyphInfos = glyphRun.glyphs.map(
|
|
52
|
+
this.glyphInfos = /** @type {LayoutGlyph[]} */ (glyphRun.glyphs).map(
|
|
53
|
+
/** @param {LayoutGlyph} glyph */ glyph => new GlyphInfo(this.font, glyph.id, [...glyph.codePoints])
|
|
54
|
+
);
|
|
29
55
|
|
|
30
56
|
// Select an OpenType script for GSUB/GPOS features.
|
|
57
|
+
/** @type {string | null} */
|
|
31
58
|
let script = null;
|
|
32
59
|
if (this.GPOSProcessor) {
|
|
33
60
|
script = this.GPOSProcessor.selectScript(glyphRun.script, glyphRun.language, glyphRun.direction);
|
|
@@ -40,12 +67,13 @@ export default class OTLayoutEngine {
|
|
|
40
67
|
// Choose the complex shaper from the buffer Unicode script (HB model). The OT
|
|
41
68
|
// script may fall back to DFLT/latn even for Thai text; that must not select
|
|
42
69
|
// DefaultShaper or Thai SARA AM / PUA preprocessing is skipped.
|
|
43
|
-
this.shaper = Shapers.choose(glyphRun.script || script);
|
|
70
|
+
this.shaper = /** @type {ShaperLike} */ (Shapers.choose(glyphRun.script || script));
|
|
44
71
|
this.plan = new ShapingPlan(this.font, script || glyphRun.script, glyphRun.direction);
|
|
45
72
|
this.plan.bufferScript = glyphRun.script;
|
|
46
73
|
this.shaper.plan(this.plan, this.glyphInfos, glyphRun.features);
|
|
47
74
|
|
|
48
75
|
// Enabled features as true, then overlay user values (e.g. aalt: 2) without mutating input.
|
|
76
|
+
/** @type {FeatureMap} */
|
|
49
77
|
let features = {};
|
|
50
78
|
for (let key in this.plan.allFeatures) {
|
|
51
79
|
features[key] = true;
|
|
@@ -53,38 +81,62 @@ export default class OTLayoutEngine {
|
|
|
53
81
|
glyphRun.features = Object.assign(features, glyphRun.features);
|
|
54
82
|
}
|
|
55
83
|
|
|
84
|
+
/**
|
|
85
|
+
* @param {GlyphRunLike} glyphRun
|
|
86
|
+
*/
|
|
56
87
|
substitute(glyphRun) {
|
|
57
|
-
if (this.GSUBProcessor) {
|
|
88
|
+
if (this.GSUBProcessor && this.plan && this.glyphInfos) {
|
|
58
89
|
this.plan.process(this.GSUBProcessor, this.glyphInfos);
|
|
59
90
|
|
|
60
91
|
// Map glyph infos back to normal Glyph objects
|
|
61
|
-
|
|
92
|
+
/** @type {LayoutGlyph[]} */
|
|
93
|
+
let glyphs = [];
|
|
94
|
+
for (let glyphInfo of this.glyphInfos) {
|
|
95
|
+
let g = this.font.getGlyph(glyphInfo.id, glyphInfo.codePoints);
|
|
96
|
+
if (g) {
|
|
97
|
+
glyphs.push(g);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
glyphRun.glyphs = glyphs;
|
|
62
101
|
}
|
|
63
102
|
}
|
|
64
103
|
|
|
104
|
+
/**
|
|
105
|
+
* @param {GlyphRunLike} glyphRun
|
|
106
|
+
* @returns {FeatureMap | Record<string, import('../../types/fontkit').OTFeature> | null | undefined | false}
|
|
107
|
+
*/
|
|
65
108
|
position(glyphRun) {
|
|
66
|
-
if (this.shaper.zeroMarkWidths === 'BEFORE_GPOS') {
|
|
109
|
+
if (this.shaper && this.shaper.zeroMarkWidths === 'BEFORE_GPOS' && glyphRun.positions) {
|
|
67
110
|
this.zeroMarkAdvances(glyphRun.positions);
|
|
68
111
|
}
|
|
69
112
|
|
|
70
|
-
if (this.GPOSProcessor) {
|
|
113
|
+
if (this.GPOSProcessor && this.plan && this.glyphInfos && glyphRun.positions) {
|
|
71
114
|
this.plan.process(this.GPOSProcessor, this.glyphInfos, glyphRun.positions);
|
|
72
115
|
}
|
|
73
116
|
|
|
74
|
-
if (this.shaper.zeroMarkWidths === 'AFTER_GPOS') {
|
|
117
|
+
if (this.shaper && this.shaper.zeroMarkWidths === 'AFTER_GPOS' && glyphRun.positions) {
|
|
75
118
|
this.zeroMarkAdvances(glyphRun.positions);
|
|
76
119
|
}
|
|
77
120
|
|
|
78
121
|
// Reverse the glyphs and positions if the script is right-to-left
|
|
79
122
|
if (glyphRun.direction === 'rtl') {
|
|
80
123
|
glyphRun.glyphs.reverse();
|
|
81
|
-
glyphRun.positions
|
|
124
|
+
if (glyphRun.positions) {
|
|
125
|
+
glyphRun.positions.reverse();
|
|
126
|
+
}
|
|
82
127
|
}
|
|
83
128
|
|
|
84
129
|
return this.GPOSProcessor && this.GPOSProcessor.features;
|
|
85
130
|
}
|
|
86
131
|
|
|
132
|
+
/**
|
|
133
|
+
* @param {GlyphPositionLike[]} positions
|
|
134
|
+
*/
|
|
87
135
|
zeroMarkAdvances(positions) {
|
|
136
|
+
if (!this.glyphInfos) {
|
|
137
|
+
return;
|
|
138
|
+
}
|
|
139
|
+
|
|
88
140
|
for (let i = 0; i < this.glyphInfos.length; i++) {
|
|
89
141
|
if (this.glyphInfos[i].isMark) {
|
|
90
142
|
positions[i].xAdvance = 0;
|
|
@@ -99,7 +151,13 @@ export default class OTLayoutEngine {
|
|
|
99
151
|
this.shaper = null;
|
|
100
152
|
}
|
|
101
153
|
|
|
154
|
+
/**
|
|
155
|
+
* @param {ScriptTag | string[] | null | undefined} script
|
|
156
|
+
* @param {LanguageTag | null | undefined} language
|
|
157
|
+
* @returns {string[]}
|
|
158
|
+
*/
|
|
102
159
|
getAvailableFeatures(script, language) {
|
|
160
|
+
/** @type {string[]} */
|
|
103
161
|
let features = [];
|
|
104
162
|
|
|
105
163
|
if (this.GSUBProcessor) {
|