import { type GlyphRun } from '../glyph-run.ts'; import { CoverageTable } from './common/coverage.ts'; import { FeatureListTable, type FeatureTable } from './common/feature-list.ts'; import { LookupListTable, type LookupTable } from './common/lookup-list.ts'; import { type LangSysTable, ScriptListTable, type ScriptTable } from './common/script-list.ts'; /** * The 'GSUB' table provides glyph substitution data for advanced * typography features like ligatures. */ export declare class GsubTable { private readonly data; readonly scriptListTable: ScriptListTable; readonly featureListTable: FeatureListTable; readonly lookupListTable: LookupListTable; /** * Reads a 'GSUB' table from the given DataView. */ static read(data: DataView): GsubTable; private constructor(); findScriptTable(scriptTag?: string): ScriptTable | undefined; findLangSysTable(scriptTable: ScriptTable, langSysTag: string | undefined): LangSysTable | undefined; findFeatureTables(featureTag: string): FeatureTable[]; } export declare function readGsubSubtable(lookupTable: LookupTable, subtableIndex: number): GsubSubtable | undefined; /** * Reads all GSUB subtables for a lookup. For Type 6 (chaining contextual), * all subtables are consolidated into a single instance so that rules are * tried in order at each glyph position (first match wins). */ export declare function readAllGsubSubtables(lookupTable: LookupTable): GsubSubtable[]; /** * Callback to apply an inner GSUB lookup at a specific glyph position. * Used by chaining contextual substitution (Type 6) to invoke referenced lookups. */ export type ApplyLookupFn = (lookupIndex: number, glyphRun: GlyphRun, targetIndex: number, getAdvance: (glyphId: number) => number) => void; export type GsubSubtable = GsubSingleSubstSubtable | GsubMultipleSubstSubtable | GsubAlternateSubstSubtable | GsubLigatureSubstSubtable | GsubContextSubstSubtable | GsubChainingContextSubstSubtable; /** * Tries to apply a list of GSUB subtables at a specific glyph position. * Subtables are tried in order; the first one that matches wins. * Returns true if any subtable matched. */ export declare function applyGsubSubtablesAtIndex(subtables: GsubSubtable[], glyphRun: GlyphRun, index: number, getAdvance: (glyphId: number) => number, skip: ((glyphId: number) => boolean) | undefined, applyLookup: ApplyLookupFn): boolean; /** * Lookup type 1 subtable: single substitution (one glyph → one glyph) * Used for features like small caps (smcp), stylistic alternates, etc. */ export declare class GsubSingleSubstSubtable { private readonly isFormat1; private readonly deltaGlyphId; private readonly substituteGlyphIds; readonly coverageTable: CoverageTable; static read(data: DataView): GsubSingleSubstSubtable; private constructor(); /** * Applies single substitution to the given glyph sequence. * For performance reasons, the glyph sequence is modified in place. */ applyToGlyphRun(glyphRun: GlyphRun, getAdvance?: (glyphId: number) => number, skip?: (glyphId: number) => boolean, _applyLookup?: ApplyLookupFn): void; /** * Tries to apply single substitution at a specific glyph position. * Returns true if the glyph was substituted. */ applyAtIndex(glyphRun: GlyphRun, index: number, getAdvance: (glyphId: number) => number, skip?: (glyphId: number) => boolean, _applyLookup?: ApplyLookupFn): boolean; } /** * Lookup type 2 subtable: multiple substitution (one glyph → many glyphs) * Used for decomposition, e.g., fi → f + i for accessibility. */ export declare class GsubMultipleSubstSubtable { private readonly sequences; readonly coverageTable: CoverageTable; static read(data: DataView): GsubMultipleSubstSubtable; private constructor(); applyToGlyphRun(glyphRun: GlyphRun, getAdvance?: (glyphId: number) => number, skip?: (glyphId: number) => boolean, _applyLookup?: ApplyLookupFn): void; applyAtIndex(glyphRun: GlyphRun, index: number, getAdvance: (glyphId: number) => number, skip?: (glyphId: number) => boolean, _applyLookup?: ApplyLookupFn): boolean; } /** * Lookup type 3 subtable: alternate substitution (one glyph → one of several alternates) * Used for features like stylistic alternates (salt), stylistic sets (ss01–ss20), etc. */ export declare class GsubAlternateSubstSubtable { private readonly alternates; readonly coverageTable: CoverageTable; static read(data: DataView): GsubAlternateSubstSubtable; private constructor(); applyToGlyphRun(glyphRun: GlyphRun, getAdvance?: (glyphId: number) => number, skip?: (glyphId: number) => boolean): void; applyAtIndex(glyphRun: GlyphRun, index: number, getAdvance: (glyphId: number) => number, skip?: (glyphId: number) => boolean): boolean; } export declare class GsubLigatureSubstSubtable { private readonly data; private readonly ligatureSetCount; private readonly ligatureSetOffsets; coverageTable: CoverageTable; ligatureSets: LigatureSetTable[]; static read(data: DataView): GsubLigatureSubstSubtable; private constructor(); /** * Applies the ligature substitution to the given glyph sequence. * For performance reasons, the glyph sequence is modified in place. * * The ligature glyph combines the codePoints from all replaced glyphs. * If a getAdvance callback is provided, it is used to set the ligature's * advance; otherwise the advance defaults to 0. */ applyToGlyphRun(glyphRun: GlyphRun, getAdvance?: (glyphId: number) => number, skip?: (glyphId: number) => boolean, _applyLookup?: ApplyLookupFn): void; /** * Tries to form a ligature starting at the given glyph position. * Returns true if a ligature was formed (glyphs are spliced in place). */ applyAtIndex(glyphRun: GlyphRun, index: number, getAdvance: (glyphId: number) => number, skip?: (glyphId: number) => boolean, _applyLookup?: ApplyLookupFn): boolean; } declare class LigatureSetTable { readonly ligatureTables: LigatureTable[]; constructor(data: DataView); } declare class LigatureTable { readonly ligGlyph: number; readonly compGlyphIDs: number[]; constructor(data: DataView); } /** * Lookup type 5 subtable: context substitution. * Matches an input sequence of glyphs and applies referenced inner lookups * to specific positions within that sequence. Unlike Type 6 (chaining * contextual), there are no backtrack or lookahead contexts. * * Supports all three formats: * - Format 1: glyph-based rules (coverage + explicit glyph ID sequences) * - Format 2: class-based rules (coverage + ClassDef + class sequences) * - Format 3: coverage-based rules (per-position coverage tables) */ export declare class GsubContextSubstSubtable { private readonly rules; static read(data: DataView): GsubContextSubstSubtable | undefined; addRules(data: DataView): boolean; applyToGlyphRun(glyphRun: GlyphRun, getAdvance?: (glyphId: number) => number, skip?: (glyphId: number) => boolean, applyLookup?: ApplyLookupFn): void; applyAtIndex(glyphRun: GlyphRun, index: number, getAdvance: (glyphId: number) => number, skip?: (glyphId: number) => boolean, applyLookup?: ApplyLookupFn): boolean; } /** * Lookup type 6 subtable: chaining contextual substitution. * Matches a sequence of glyphs with backtrack, input, and lookahead * contexts, then applies referenced inner lookups to specific input glyphs. * * A lookup may contain multiple subtables (rules) that are tried in order * at each glyph position — the first matching rule wins. To support this, * all subtables of a Type 6 lookup are collected into a single instance * via the `addRule` method. * * Currently supports Format 3 (coverage-based) only. */ export declare class GsubChainingContextSubstSubtable { private readonly rules; static read(data: DataView): GsubChainingContextSubstSubtable | undefined; addRule(data: DataView): boolean; applyToGlyphRun(glyphRun: GlyphRun, getAdvance?: (glyphId: number) => number, skip?: (glyphId: number) => boolean, applyLookup?: ApplyLookupFn): void; /** * Tries to match a chaining contextual rule at the given glyph position. * Returns true if a rule matched and inner lookups were applied. */ applyAtIndex(glyphRun: GlyphRun, index: number, getAdvance: (glyphId: number) => number, skip?: (glyphId: number) => boolean, applyLookup?: ApplyLookupFn): boolean; } export {};