Closed RoelN closed 3 years ago
Possibly related to https://github.com/Pomax/lib-font/issues/105 ?
I've slightly changed the test code to not single out lookup type 6:
function testFont(font) {
const { GSUB } = font.opentype.tables;
const scripts = GSUB.getSupportedScripts();
let allGlyphs = {};
scripts.forEach((script) => {
let langsys = GSUB.getSupportedLangSys(script);
allGlyphs[script] = {};
langsys.forEach((lang) => {
let langSysTable = GSUB.getLangSysTable(script, lang);
let features = GSUB.getFeatures(langSysTable);
allGlyphs[script][lang] = {};
features.forEach((feature) => {
const lookupIDs = feature.lookupListIndices;
allGlyphs[script][lang][feature.featureTag] = {};
allGlyphs[script][lang][feature.featureTag]["lookups"] = [];
lookupIDs.forEach((id) => {
const lookup = GSUB.getLookup(id);
lookup.subtableOffsets.forEach((_, i) => {
console.log(
`Getting subtable ${i}, lookup ${id}, feature ${feature.featureTag}, script ${script} , lang ${lang}`
);
const subtable = lookup.getSubTable(i);
});
});
});
});
});
}
This yields:
Getting subtable 0, lookup 14, feature c2sc, script latn , lang dflt
Getting subtable 0, lookup 15, feature c2sc, script latn , lang dflt
Getting subtable 0, lookup 17, feature case, script latn , lang dflt
Getting subtable 0, lookup 18, feature case, script latn , lang dflt
Getting subtable 0, lookup 4, feature ccmp, script latn , lang dflt
Getting subtable 0, lookup 5, feature ccmp, script latn , lang dflt
Getting subtable 0, lookup 6, feature ccmp, script latn , lang dflt
parser getUint16 2 Parser {
name: 'GSUB',
length: 6524,
start: 4554,
offset: 1972,
data: DataView {
byteLength: 6524,
byteOffset: 0,
buffer: ArrayBuffer {
[Uint8Contents]: <00 01 00 00 00 0a 00 b4 01 66 00 01 6c 61 74 6e 00 08 00 22 00 05 43 41 54 20 00 3a 4d 4f 4c 20 00 6e 4e 4c 44 20 00 54 52 4f 4d 20 00 6e 54 52 4b 20 00 88 00 00 ff ff 00 09 00 00 00 01 00 02 00 03 00 04 00 05 00 0a 00 0b 00 0c 00 00 ff ff 00 0a 00 00 00 01 00 02 00 03 00 04 00 05 00 06 00 0a 00 0b ... 6424 more bytes>,
byteLength: 6524
}
}
}
parser 4554 1972
RangeError: Offset is outside the bounds of the DataView
at DataView.getUint16 (<anonymous>)
at Parser.getValue (file:///C:/Users/Mike/Documents/Git/released/lib-font/src/parser.js:60:29)
at Parser.get (file:///C:/Users/Mike/Documents/Git/released/lib-font/src/parser.js:38:25)
at Parser.get Offset16 [as Offset16] (file:///C:/Users/Mike/Documents/Git/released/lib-font/src/parser.js:130:17)
at file:///C:/Users/Mike/Documents/Git/released/lib-font/src/opentype/tables/advanced/shared/subtables/lookuptypes/gsub-6.js:26:22
at Array.map (<anonymous>)
at new LookupType6 (file:///C:/Users/Mike/Documents/Git/released/lib-font/src/opentype/tables/advanced/shared/subtables/lookuptypes/gsub-6.js:26:9)
at Object.buildSubtable (file:///C:/Users/Mike/Documents/Git/released/lib-font/src/opentype/tables/advanced/shared/subtables/gsub.js:24:16)
at LookupTable.getSubTable (file:///C:/Users/Mike/Documents/Git/released/lib-font/src/opentype/tables/advanced/shared/lookup.js:53:20)
at file:///C:/Users/Mike/Documents/Git/released/lib-font/testing/manual/custom/castoro-parsing.js:42:37
Looking at getSubTable()
and adding a try/catch:
getSubTable(index) {
const builder = this.ctType === `GSUB` ? GSUBtables : GPOStables;
this.parser.currentPosition = this.start + this.subtableOffsets[index];
console.log(`getSubTable(${index}): this.parser.currentPosition = ${this.start} + ${this.subtableOffsets[index]}`)
try {
return builder.buildSubtable(this.lookupType, this.parser);
} catch (e) {
console.log({
...this,
start: this.start
});
throw e;
}
}
Yields:
Getting subtable 0, lookup 14, feature c2sc, script latn , lang dflt
getSubTable(0): this.parser.currentPosition = 5002 + 8
Getting subtable 0, lookup 15, feature c2sc, script latn , lang dflt
getSubTable(0): this.parser.currentPosition = 5462 + 8
Getting subtable 0, lookup 17, feature case, script latn , lang dflt
getSubTable(0): this.parser.currentPosition = 5982 + 8
Getting subtable 0, lookup 18, feature case, script latn , lang dflt
getSubTable(0): this.parser.currentPosition = 6060 + 8
Getting subtable 0, lookup 4, feature ccmp, script latn , lang dflt
getSubTable(0): this.parser.currentPosition = 620 + 8
Getting subtable 0, lookup 5, feature ccmp, script latn , lang dflt
getSubTable(0): this.parser.currentPosition = 3926 + 8
Getting subtable 0, lookup 6, feature ccmp, script latn , lang dflt
getSubTable(0): this.parser.currentPosition = 4546 + 8
going
parser getUint16 2 Parser {
name: 'GSUB',
length: 6524,
start: 4554,
offset: 1972,
data: DataView {
byteLength: 6524,
byteOffset: 0,
buffer: ArrayBuffer {
[Uint8Contents]: <00 01 00 00 00 0a 00 b4 01 66 00 01 6c 61 74 6e 00 08 00 22 00 05 43 41 54 20 00 3a 4d 4f 4c 20 00 6e 4e 4c 44 20 00 54 52 4f 4d 20 00 6e 54 52 4b 20 00 88 00 00 ff ff 00 09 00 00 00 01 00 02 00 03 00 04 00 05 00 0a 00 0b 00 0c 00 00 ff ff 00 0a 00 00 00 01 00 02 00 03 00 04 00 05 00 06 00 0a 00 0b ... 6424 more bytes>,
byteLength: 6524
}
}
}
parser 4554 1972
{
ctType: 'GSUB',
lookupType: 6,
lookupFlag: 0,
subTableCount: 1,
subtableOffsets: [ 8 ],
markFilteringSet: 2,
start: 4546
}
RangeError: Offset is outside the bounds of the DataView
at DataView.getUint16 (<anonymous>)
at Parser.getValue (file:///C:/Users/Mike/Documents/Git/released/lib-font/src/parser.js:60:29)
at Parser.get (file:///C:/Users/Mike/Documents/Git/released/lib-font/src/parser.js:38:25)
at Parser.get Offset16 [as Offset16] (file:///C:/Users/Mike/Documents/Git/released/lib-font/src/parser.js:130:17)
at file:///C:/Users/Mike/Documents/Git/released/lib-font/src/opentype/tables/advanced/lookups/gsub/lookup-type-6.js:32:22
at Array.map (<anonymous>)
at new LookupType6 (file:///C:/Users/Mike/Documents/Git/released/lib-font/src/opentype/tables/advanced/lookups/gsub/lookup-type-6.js:32:9)
at Object.buildSubtable (file:///C:/Users/Mike/Documents/Git/released/lib-font/src/opentype/tables/advanced/shared/subtables/gsub.js:24:16)
at LookupTable.getSubTable (file:///C:/Users/Mike/Documents/Git/released/lib-font/src/opentype/tables/advanced/shared/lookup.js:55:22)
at file:///C:/Users/Mike/Documents/Git/released/lib-font/testing/manual/custom/castoro-parsing.js:42:37
Updating the GSUB lookup6 class:
class LookupType6 extends LookupType {
constructor(p) {
super(p);
console.log(`building GSUB lookup type 6 subtable, with substFormat ${this.substFormat}`);
Shows:
...
Getting subtable 0, lookup 6, feature ccmp, script latn , lang dflt
getSubTable(0): this.parser.currentPosition = 4546 + 8
building GSUB lookup type 6 subtable, with substFormat 2
So let's investigate the code specific to 6.2
...
if (this.substFormat === 2) {
this.coverageOffset = p.Offset16;
this.backtrackClassDefOffset = p.Offset16;
this.inputClassDefOffset = p.Offset16;
this.lookaheadClassDefOffset = p.Offset16;
this.chainSubClassSetCount = p.uint16;
console.log(`Data found prior to binding this.chainSubClassSetOffsets:`, {
coverageOffset: this.coverageOffset,
backtrackClassDefOffset: this.backtrackClassDefOffset,
inputClassDefOffset: this.inputClassDefOffset,
lookaheadClassDefOffset: this.lookaheadClassDefOffset,
chainSubClassSetCount: this.chainSubClassSetCount,
});
this.chainSubClassSetOffsets = [
...new Array(this.chainSubClassSetCount),
].map((_) => p.Offset16);
}
...
Yields:
Getting subtable 0, lookup 6, feature ccmp, script latn , lang dflt
getSubTable(0): this.parser.currentPosition = 4546 + 8
building GSUB lookup type 6 subtable, with substFormat 2
Data found prior to binding this.chainSubClassSetOffsets: {
coverageOffset: 42,
backtrackClassDefOffset: 130,
inputClassDefOffset: 1556,
lookaheadClassDefOffset: 15,
chainSubClassSetCount: 1634
}
And that might be a valid chainSubClassSetCount
but it looks terribly suspicious
...
console.log(`Trying to build this.chainSubClassSetOffsets...`)
try {
this.chainSubClassSetOffsets = [
...new Array(this.chainSubClassSetCount),
].map((_) => p.Offset16);
} catch (e) {
console.error(`yeah that failed.`);
throw e;
}
Shows
Getting subtable 0, lookup 6, feature ccmp, script latn , lang dflt
getSubTable(0): this.parser.currentPosition = 4546 + 8
building GSUB lookup type 6 subtable, with substFormat 2
Data found prior to binding this.chainSubClassSetOffsets: {
coverageOffset: 42,
backtrackClassDefOffset: 130,
inputClassDefOffset: 1556,
lookaheadClassDefOffset: 15,
chainSubClassSetCount: 1634
}
Trying to build this.chainSubClassSetOffsets...
yeah that failed.
Time to break out the documentation: https://docs.microsoft.com/en-us/typography/opentype/spec/gsub#lookuptype-6-chained-contexts-substitution-subtable tells us that we also need to look at https://docs.microsoft.com/en-us/typography/opentype/spec/chapter2#chseqctxt2
Our table format should be:
Type | Name | Description |
---|---|---|
uint16 | format | Format identifier: format = 2 |
Offset16 | coverageOffset | Offset to Coverage table, from beginning of ChainedSequenceContextFormat2 table |
Offset16 | backtrackClassDefOffset | Offset to ClassDef table containing backtrack sequence context, from beginning of ChainedSequenceContextFormat2 table |
Offset16 | inputClassDefOffset | Offset to ClassDef table containing input sequence context, from beginning of ChainedSequenceContextFormat2 table |
Offset16 | lookaheadClassDefOffset | Offset to ClassDef table containing lookahead sequence context, from beginning of ChainedSequenceContextFormat2 table |
uint16 | chainedClassSeqRuleSetCount | Number of ChainedClassSequenceRuleSet tables |
Offset16 | chainedClassSeqRuleSetOffsets[chainedClassSeqRuleSetCount] | Array of offsets to ChainedClassSequenceRuleSet tables, from beginning of ChainedSequenceContextFormat2 table (may be NULL) |
In the subtable we see:
class LookupType6 extends LookupType {
constructor(p) {
super(p);
...
if (this.substFormat === 2) {
this.coverageOffset = p.Offset16;
this.backtrackClassDefOffset = p.Offset16;
this.inputClassDefOffset = p.Offset16;
this.lookaheadClassDefOffset = p.Offset16;
this.chainSubClassSetCount = p.uint16;
But if we look at the super class, we see:
class LookupType extends ParsedData {
constructor(p) {
super(p);
this.substFormat = p.uint16;
this.coverageOffset = p.Offset16;
}
So there's our bug: we're double-parsing this.coverageOffset
, once in the super class, and then again in the specific class
Removing the erroneous double parse from the LookupType6
class:
class LookupType6 extends LookupType {
constructor(p) {
super(p);
...
if (this.substFormat === 2) {
this.backtrackClassDefOffset = p.Offset16;
this.inputClassDefOffset = p.Offset16;
this.lookaheadClassDefOffset = p.Offset16;
this.chainSubClassSetCount = p.uint16;
this.chainSubClassSetOffsets = [
...new Array(this.chainSubClassSetCount),
].map((_) => p.Offset16);
}
...
With updated test:
...
lookup.subtableOffsets.forEach((_, i) => {
const subtable = lookup.getSubTable(i);
console.log(
`Getting lookup ${`${id}`.padStart(2, ' ')}, subtable ${i}, lookuptype ${subtable.type}, format ${subtable.substFormat}, feature ${feature.featureTag}, script ${script}, lang ${lang}`
);
});
...
Now gives us:
Getting lookup 14, subtable 0, lookuptype 1, format 2, feature c2sc, script latn, lang dflt
Getting lookup 15, subtable 0, lookuptype 1, format 1, feature c2sc, script latn, lang dflt
Getting lookup 17, subtable 0, lookuptype 1, format 2, feature case, script latn, lang dflt
Getting lookup 18, subtable 0, lookuptype 1, format 1, feature case, script latn, lang dflt
Getting lookup 4, subtable 0, lookuptype 4, format 1, feature ccmp, script latn, lang dflt
Getting lookup 5, subtable 0, lookuptype 4, format 1, feature ccmp, script latn, lang dflt
Getting lookup 6, subtable 0, lookuptype 6, format 2, feature ccmp, script latn, lang dflt
Getting lookup 10, subtable 0, lookuptype 1, format 2, feature frac, script latn, lang dflt
Getting lookup 11, subtable 0, lookuptype 1, format 1, feature frac, script latn, lang dflt
Getting lookup 12, subtable 0, lookuptype 6, format 2, feature frac, script latn, lang dflt
Getting lookup 19, subtable 0, lookuptype 6, format 2, feature liga, script latn, lang dflt
Getting lookup 21, subtable 0, lookuptype 6, format 3, feature liga, script latn, lang dflt
Getting lookup 21, subtable 1, lookuptype 6, format 3, feature liga, script latn, lang dflt
Getting lookup 23, subtable 0, lookuptype 6, format 3, feature liga, script latn, lang dflt
Getting lookup 23, subtable 1, lookuptype 6, format 3, feature liga, script latn, lang dflt
Getting lookup 25, subtable 0, lookuptype 6, format 1, feature liga, script latn, lang dflt
Getting lookup 27, subtable 0, lookuptype 6, format 1, feature liga, script latn, lang dflt
Getting lookup 18, subtable 0, lookuptype 1, format 1, feature lnum, script latn, lang dflt
Getting lookup 16, subtable 0, lookuptype 1, format 2, feature smcp, script latn, lang dflt
Getting lookup 9, subtable 0, lookuptype 1, format 1, feature subs, script latn, lang dflt
Getting lookup 8, subtable 0, lookuptype 1, format 1, feature sups, script latn, lang dflt
Getting lookup 14, subtable 0, lookuptype 1, format 2, feature c2sc, script latn, lang CAT
Getting lookup 15, subtable 0, lookuptype 1, format 1, feature c2sc, script latn, lang CAT
Getting lookup 17, subtable 0, lookuptype 1, format 2, feature case, script latn, lang CAT
Getting lookup 18, subtable 0, lookuptype 1, format 1, feature case, script latn, lang CAT
Getting lookup 4, subtable 0, lookuptype 4, format 1, feature ccmp, script latn, lang CAT
Getting lookup 5, subtable 0, lookuptype 4, format 1, feature ccmp, script latn, lang CAT
Getting lookup 6, subtable 0, lookuptype 6, format 2, feature ccmp, script latn, lang CAT
Getting lookup 10, subtable 0, lookuptype 1, format 2, feature frac, script latn, lang CAT
Getting lookup 11, subtable 0, lookuptype 1, format 1, feature frac, script latn, lang CAT
Getting lookup 12, subtable 0, lookuptype 6, format 2, feature frac, script latn, lang CAT
Getting lookup 19, subtable 0, lookuptype 6, format 2, feature liga, script latn, lang CAT
Getting lookup 21, subtable 0, lookuptype 6, format 3, feature liga, script latn, lang CAT
Getting lookup 21, subtable 1, lookuptype 6, format 3, feature liga, script latn, lang CAT
Getting lookup 23, subtable 0, lookuptype 6, format 3, feature liga, script latn, lang CAT
Getting lookup 23, subtable 1, lookuptype 6, format 3, feature liga, script latn, lang CAT
Getting lookup 25, subtable 0, lookuptype 6, format 1, feature liga, script latn, lang CAT
Getting lookup 27, subtable 0, lookuptype 6, format 1, feature liga, script latn, lang CAT
Getting lookup 18, subtable 0, lookuptype 1, format 1, feature lnum, script latn, lang CAT
Getting lookup 0, subtable 0, lookuptype 4, format 1, feature locl, script latn, lang CAT
Getting lookup 16, subtable 0, lookuptype 1, format 2, feature smcp, script latn, lang CAT
Getting lookup 9, subtable 0, lookuptype 1, format 1, feature subs, script latn, lang CAT
Getting lookup 8, subtable 0, lookuptype 1, format 1, feature sups, script latn, lang CAT
Getting lookup 14, subtable 0, lookuptype 1, format 2, feature c2sc, script latn, lang MOL
Getting lookup 15, subtable 0, lookuptype 1, format 1, feature c2sc, script latn, lang MOL
Getting lookup 17, subtable 0, lookuptype 1, format 2, feature case, script latn, lang MOL
Getting lookup 18, subtable 0, lookuptype 1, format 1, feature case, script latn, lang MOL
Getting lookup 4, subtable 0, lookuptype 4, format 1, feature ccmp, script latn, lang MOL
Getting lookup 5, subtable 0, lookuptype 4, format 1, feature ccmp, script latn, lang MOL
Getting lookup 6, subtable 0, lookuptype 6, format 2, feature ccmp, script latn, lang MOL
Getting lookup 10, subtable 0, lookuptype 1, format 2, feature frac, script latn, lang MOL
Getting lookup 11, subtable 0, lookuptype 1, format 1, feature frac, script latn, lang MOL
Getting lookup 12, subtable 0, lookuptype 6, format 2, feature frac, script latn, lang MOL
Getting lookup 19, subtable 0, lookuptype 6, format 2, feature liga, script latn, lang MOL
Getting lookup 21, subtable 0, lookuptype 6, format 3, feature liga, script latn, lang MOL
Getting lookup 21, subtable 1, lookuptype 6, format 3, feature liga, script latn, lang MOL
Getting lookup 23, subtable 0, lookuptype 6, format 3, feature liga, script latn, lang MOL
Getting lookup 23, subtable 1, lookuptype 6, format 3, feature liga, script latn, lang MOL
Getting lookup 25, subtable 0, lookuptype 6, format 1, feature liga, script latn, lang MOL
Getting lookup 27, subtable 0, lookuptype 6, format 1, feature liga, script latn, lang MOL
Getting lookup 18, subtable 0, lookuptype 1, format 1, feature lnum, script latn, lang MOL
Getting lookup 2, subtable 0, lookuptype 1, format 1, feature locl, script latn, lang MOL
Getting lookup 16, subtable 0, lookuptype 1, format 2, feature smcp, script latn, lang MOL
Getting lookup 9, subtable 0, lookuptype 1, format 1, feature subs, script latn, lang MOL
Getting lookup 8, subtable 0, lookuptype 1, format 1, feature sups, script latn, lang MOL
Getting lookup 14, subtable 0, lookuptype 1, format 2, feature c2sc, script latn, lang NLD
Getting lookup 15, subtable 0, lookuptype 1, format 1, feature c2sc, script latn, lang NLD
Getting lookup 17, subtable 0, lookuptype 1, format 2, feature case, script latn, lang NLD
Getting lookup 18, subtable 0, lookuptype 1, format 1, feature case, script latn, lang NLD
Getting lookup 4, subtable 0, lookuptype 4, format 1, feature ccmp, script latn, lang NLD
Getting lookup 5, subtable 0, lookuptype 4, format 1, feature ccmp, script latn, lang NLD
Getting lookup 6, subtable 0, lookuptype 6, format 2, feature ccmp, script latn, lang NLD
Getting lookup 10, subtable 0, lookuptype 1, format 2, feature frac, script latn, lang NLD
Getting lookup 11, subtable 0, lookuptype 1, format 1, feature frac, script latn, lang NLD
Getting lookup 12, subtable 0, lookuptype 6, format 2, feature frac, script latn, lang NLD
Getting lookup 19, subtable 0, lookuptype 6, format 2, feature liga, script latn, lang NLD
Getting lookup 21, subtable 0, lookuptype 6, format 3, feature liga, script latn, lang NLD
Getting lookup 21, subtable 1, lookuptype 6, format 3, feature liga, script latn, lang NLD
Getting lookup 23, subtable 0, lookuptype 6, format 3, feature liga, script latn, lang NLD
Getting lookup 23, subtable 1, lookuptype 6, format 3, feature liga, script latn, lang NLD
Getting lookup 25, subtable 0, lookuptype 6, format 1, feature liga, script latn, lang NLD
Getting lookup 27, subtable 0, lookuptype 6, format 1, feature liga, script latn, lang NLD
Getting lookup 18, subtable 0, lookuptype 1, format 1, feature lnum, script latn, lang NLD
Getting lookup 1, subtable 0, lookuptype 4, format 1, feature locl, script latn, lang NLD
Getting lookup 16, subtable 0, lookuptype 1, format 2, feature smcp, script latn, lang NLD
Getting lookup 9, subtable 0, lookuptype 1, format 1, feature subs, script latn, lang NLD
Getting lookup 8, subtable 0, lookuptype 1, format 1, feature sups, script latn, lang NLD
Getting lookup 14, subtable 0, lookuptype 1, format 2, feature c2sc, script latn, lang ROM
Getting lookup 15, subtable 0, lookuptype 1, format 1, feature c2sc, script latn, lang ROM
Getting lookup 17, subtable 0, lookuptype 1, format 2, feature case, script latn, lang ROM
Getting lookup 18, subtable 0, lookuptype 1, format 1, feature case, script latn, lang ROM
Getting lookup 4, subtable 0, lookuptype 4, format 1, feature ccmp, script latn, lang ROM
Getting lookup 5, subtable 0, lookuptype 4, format 1, feature ccmp, script latn, lang ROM
Getting lookup 6, subtable 0, lookuptype 6, format 2, feature ccmp, script latn, lang ROM
Getting lookup 10, subtable 0, lookuptype 1, format 2, feature frac, script latn, lang ROM
Getting lookup 11, subtable 0, lookuptype 1, format 1, feature frac, script latn, lang ROM
Getting lookup 12, subtable 0, lookuptype 6, format 2, feature frac, script latn, lang ROM
Getting lookup 19, subtable 0, lookuptype 6, format 2, feature liga, script latn, lang ROM
Getting lookup 21, subtable 0, lookuptype 6, format 3, feature liga, script latn, lang ROM
Getting lookup 21, subtable 1, lookuptype 6, format 3, feature liga, script latn, lang ROM
Getting lookup 23, subtable 0, lookuptype 6, format 3, feature liga, script latn, lang ROM
Getting lookup 23, subtable 1, lookuptype 6, format 3, feature liga, script latn, lang ROM
Getting lookup 25, subtable 0, lookuptype 6, format 1, feature liga, script latn, lang ROM
Getting lookup 27, subtable 0, lookuptype 6, format 1, feature liga, script latn, lang ROM
Getting lookup 18, subtable 0, lookuptype 1, format 1, feature lnum, script latn, lang ROM
Getting lookup 2, subtable 0, lookuptype 1, format 1, feature locl, script latn, lang ROM
Getting lookup 16, subtable 0, lookuptype 1, format 2, feature smcp, script latn, lang ROM
Getting lookup 9, subtable 0, lookuptype 1, format 1, feature subs, script latn, lang ROM
Getting lookup 8, subtable 0, lookuptype 1, format 1, feature sups, script latn, lang ROM
Getting lookup 14, subtable 0, lookuptype 1, format 2, feature c2sc, script latn, lang TRK
Getting lookup 15, subtable 0, lookuptype 1, format 1, feature c2sc, script latn, lang TRK
Getting lookup 17, subtable 0, lookuptype 1, format 2, feature case, script latn, lang TRK
Getting lookup 18, subtable 0, lookuptype 1, format 1, feature case, script latn, lang TRK
Getting lookup 4, subtable 0, lookuptype 4, format 1, feature ccmp, script latn, lang TRK
Getting lookup 5, subtable 0, lookuptype 4, format 1, feature ccmp, script latn, lang TRK
Getting lookup 6, subtable 0, lookuptype 6, format 2, feature ccmp, script latn, lang TRK
Getting lookup 10, subtable 0, lookuptype 1, format 2, feature frac, script latn, lang TRK
Getting lookup 11, subtable 0, lookuptype 1, format 1, feature frac, script latn, lang TRK
Getting lookup 12, subtable 0, lookuptype 6, format 2, feature frac, script latn, lang TRK
Getting lookup 19, subtable 0, lookuptype 6, format 2, feature liga, script latn, lang TRK
Getting lookup 21, subtable 0, lookuptype 6, format 3, feature liga, script latn, lang TRK
Getting lookup 21, subtable 1, lookuptype 6, format 3, feature liga, script latn, lang TRK
Getting lookup 23, subtable 0, lookuptype 6, format 3, feature liga, script latn, lang TRK
Getting lookup 23, subtable 1, lookuptype 6, format 3, feature liga, script latn, lang TRK
Getting lookup 25, subtable 0, lookuptype 6, format 1, feature liga, script latn, lang TRK
Getting lookup 27, subtable 0, lookuptype 6, format 1, feature liga, script latn, lang TRK
Getting lookup 18, subtable 0, lookuptype 1, format 1, feature lnum, script latn, lang TRK
Getting lookup 3, subtable 0, lookuptype 1, format 1, feature locl, script latn, lang TRK
Getting lookup 16, subtable 0, lookuptype 1, format 2, feature smcp, script latn, lang TRK
Getting lookup 9, subtable 0, lookuptype 1, format 1, feature subs, script latn, lang TRK
Getting lookup 8, subtable 0, lookuptype 1, format 1, feature sups, script latn, lang TRK
PR incoming
PR #125 merged, v2.3.3 published to npm
Twitter thread where this was first raised: https://twitter.com/TiroTypeworks/status/1356325050782150656
Font can be downloaded here: https://github.com/TiroTypeworks/Castoro (I used this WOFF2)
Here's a reduced test case:
Running this yields: