Summary
font.stringToGlyphs() throws for fonts whose GSUB uses a Chaining Context Substitution (lookup type 6), format 3 whose SubstLookupRecord points to a Single Substitution (lookup type 1), format 1 lookup.
Error: Substitution type 11 is not supported in chaining substitution
chainingSubstitutionFormat3 (in src/features/featureQuery.mjs) only handles the nested substitution types "12" (Single, format 2) and "21" (Multiple, format 1), and throws for anything else. A nested Single/format-1 lookup resolves to "11", which is not handled.
Current Behavior
stringToGlyphs() throws Error: Substitution type 11 is not supported in chaining substitution and shaping aborts for the whole run.
Expected Behavior
The nested Single (format 1) substitution should be applied (same as Single format 2), and stringToGlyphs() should return the substituted glyphs without throwing.
Steps to Reproduce
Any font with a GSUB ChainContextSubst (type 6) format-3 subtable whose SubstLookupRecord references a Single-format-1 lookup triggers this. A concrete open-source example is Noto Sans Thai Looped (Google Fonts, OFL): the ccmp feature substitutes ฬ (U+0E2C) to a short-tail variant when an above mark follows, via a chaining context whose nested lookup is a Single/format-1 substitution.
import opentype from "opentype.js";
import fs from "fs";
const buf = fs.readFileSync("NotoSansThaiLooped-Regular.otf");
const font = opentype.parse(buf.buffer.slice(buf.byteOffset, buf.byteOffset + buf.byteLength));
// U+0E2C (ฬ) + U+0E34 (above vowel ◌ิ)
font.stringToGlyphs("ฬิ"); // throws: Substitution type 11 is not supported in chaining substitution
Related
Your Environment
- opentype.js version: 2.0.0 (latest on npm)
- Environment: Node.js (also reproducible in browsers)
Summary
font.stringToGlyphs()throws for fonts whose GSUB uses a Chaining Context Substitution (lookup type 6), format 3 whoseSubstLookupRecordpoints to a Single Substitution (lookup type 1), format 1 lookup.chainingSubstitutionFormat3(insrc/features/featureQuery.mjs) only handles the nested substitution types"12"(Single, format 2) and"21"(Multiple, format 1), and throws for anything else. A nested Single/format-1 lookup resolves to"11", which is not handled.Current Behavior
stringToGlyphs()throwsError: Substitution type 11 is not supported in chaining substitutionand shaping aborts for the whole run.Expected Behavior
The nested Single (format 1) substitution should be applied (same as Single format 2), and
stringToGlyphs()should return the substituted glyphs without throwing.Steps to Reproduce
Any font with a GSUB ChainContextSubst (type 6) format-3 subtable whose
SubstLookupRecordreferences a Single-format-1 lookup triggers this. A concrete open-source example is Noto Sans Thai Looped (Google Fonts, OFL): theccmpfeature substitutes ฬ (U+0E2C) to a short-tail variant when an above mark follows, via a chaining context whose nested lookup is a Single/format-1 substitution.Related
"21"handling for Arabic/emoji, but not"11".Your Environment