Skip to content

Chaining substitution throws on nested Single (type 1, format 1) lookups #860

Description

@fifzteen

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)

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions