import { GlyphBuffer } from "../buffer/glyph-buffer.ts"; import type { UnicodeBuffer } from "../buffer/unicode-buffer.ts"; import { Face } from "../font/face.ts"; import type { Font } from "../font/font.ts"; import { type AnyGposLookup, type CursivePosLookup, type MarkBasePosLookup, type MarkLigaturePosLookup, type MarkMarkPosLookup, type PairPosLookup, type SinglePosLookup } from "../font/tables/gpos.ts"; import type { ChainingContextPosFormat1, ChainingContextPosFormat2, ChainingContextPosFormat3, ChainingContextPosLookup, ContextPosFormat1, ContextPosFormat2, ContextPosFormat3, ContextPosLookup, PosLookupRecord } from "../font/tables/gpos-contextual.ts"; import { type AlternateSubstLookup, type AnyGsubLookup, type ChainingContextSubstLookup, type ContextSubstLookup, type LigatureSubstLookup, type MultipleSubstLookup, type ReverseChainingSingleSubstLookup, type SingleSubstLookup } from "../font/tables/gsub.ts"; import type { ChainingContextFormat1, ChainingContextFormat2, ChainingContextFormat3, ContextSubstFormat1, ContextSubstFormat2, ContextSubstFormat3, SequenceLookupRecord } from "../font/tables/gsub-contextual.ts"; import type { ClassDef } from "../layout/structures/class-def.ts"; import type { GlyphId } from "../types.ts"; import { type ShapeFeature, type ShapePlan } from "./shape-plan.ts"; /** * Options for controlling text shaping behavior. */ export interface ShapeOptions { /** ISO 15924 script tag (e.g., "arab", "deva", "latn"). Defaults to buffer.script or "latn" */ script?: string; /** BCP 47 language tag (e.g., "en", "ar-SA", "hi-IN"). Defaults to buffer.language or null */ language?: string | null; /** Text direction: "ltr" (left-to-right) or "rtl" (right-to-left). Defaults to "ltr" */ direction?: "ltr" | "rtl"; /** Array of OpenType features to apply (e.g., [{tag: "liga", value: 1}, {tag: "kern", value: 0}]) */ features?: ShapeFeature[]; } /** * Union type accepting either Font or Face instances. * Use Face for variable fonts to provide axis coordinates for feature variations. * Use Font for static fonts or when default axis values are acceptable. */ export type FontLike = Font | Face; /** * Pre-computed skip markers for efficient glyph skipping in contextual matching. * Bit is set to 1 if glyph at that position should be skipped for the given lookup flag. */ type SkipMarkers = Uint8Array; /** * Pre-compute skip markers for all glyphs in the buffer. * This avoids calling shouldSkipGlyph() repeatedly in tight loops. * O(n) one-time cost instead of O(n²) repeated calls. */ declare function precomputeSkipMarkers(font: Font, buffer: GlyphBuffer, lookupFlag: number): SkipMarkers; /** * Pre-compute next non-skip index array for O(1) pair lookups. * nextNonSkip[i] = index of next non-skipped glyph after i, or -1 if none. * Built in reverse for O(n) construction. */ declare function buildNextNonSkipArray(skip: SkipMarkers, length: number): Int16Array; /** * Return a GlyphBuffer to the pool for reuse. * Call this when done with a buffer from shape() to reduce allocations. * The pool has a maximum size, so buffers beyond that limit will be discarded. * * @param buffer - The GlyphBuffer to return to the pool */ export declare function releaseBuffer(buffer: GlyphBuffer): void; /** * Shape text using OpenType features and complex script processing. * * Text shaping is the process of converting Unicode text into positioned glyphs for rendering. * This involves: * - Mapping characters to glyphs via the font's cmap table * - Applying OpenType GSUB substitutions (ligatures, contextual forms, etc.) * - Positioning glyphs via GPOS or fallback kerning/mark positioning * - Complex script analysis (Arabic joining, Indic reordering, etc.) * - Applying OpenType features (liga, kern, calt, etc.) * * The function returns a pooled GlyphBuffer for efficiency. Call releaseBuffer() when done * to return it to the pool for reuse. * * @param fontLike - Font or Face instance (Face for variable fonts with axis coordinates) * @param buffer - UnicodeBuffer containing the input text and metadata (script, language, direction) * @param options - Optional shaping parameters * @param options.script - ISO 15924 script tag (e.g., "arab", "deva"), defaults to buffer.script or "latn" * @param options.language - BCP 47 language tag (e.g., "en", "ar-SA"), defaults to buffer.language or null * @param options.direction - Text direction "ltr" or "rtl", defaults to "ltr" * @param options.features - Array of OpenType features to enable/disable (e.g., [{tag: "liga", value: 1}]) * @returns GlyphBuffer containing shaped glyphs with positions and metadata */ export declare function shape(fontLike: FontLike, buffer: UnicodeBuffer, options?: ShapeOptions): GlyphBuffer; /** * Shape text into an existing GlyphBuffer (zero-allocation hot path). * * This is a performance-optimized version of shape() that reuses an existing GlyphBuffer * instead of allocating a new one. Use this for maximum performance when shaping repeatedly, * such as in animation loops or batch text processing. * * The provided GlyphBuffer will be reset and filled with the shaped output. This avoids * allocations from the buffer pool and gives you full control over buffer lifecycle. * * @param fontLike - Font or Face instance (Face for variable fonts with axis coordinates) * @param buffer - UnicodeBuffer containing the input text and metadata (script, language, direction) * @param glyphBuffer - Existing GlyphBuffer to fill with shaped output (will be reset) * @param options - Optional shaping parameters * @param options.script - ISO 15924 script tag (e.g., "arab", "deva"), defaults to buffer.script or "latn" * @param options.language - BCP 47 language tag (e.g., "en", "ar-SA"), defaults to buffer.language or null * @param options.direction - Text direction "ltr" or "rtl", defaults to "ltr" * @param options.features - Array of OpenType features to enable/disable (e.g., [{tag: "liga", value: 1}]) */ export declare function shapeInto(fontLike: FontLike, buffer: UnicodeBuffer, glyphBuffer: GlyphBuffer, options?: ShapeOptions): void; declare function applyGsub(font: Font, buffer: GlyphBuffer, plan: ShapePlan): void; declare function applyGsubLookup(font: Font, buffer: GlyphBuffer, lookup: AnyGsubLookup, plan: ShapePlan): void; declare function applySingleSubstLookup(font: Font, buffer: GlyphBuffer, lookup: SingleSubstLookup): void; declare function applyMultipleSubstLookup(font: Font, buffer: GlyphBuffer, lookup: MultipleSubstLookup): void; declare function applyAlternateSubstLookup(font: Font, buffer: GlyphBuffer, lookup: AlternateSubstLookup): void; declare function applyLigatureSubstLookup(font: Font, buffer: GlyphBuffer, lookup: LigatureSubstLookup): void; declare function applyContextSubstLookup(font: Font, buffer: GlyphBuffer, lookup: ContextSubstLookup, plan: ShapePlan): void; declare function applyChainingContextSubstLookup(font: Font, buffer: GlyphBuffer, lookup: ChainingContextSubstLookup, plan: ShapePlan): void; declare function applyReverseChainingSingleSubstLookup(font: Font, buffer: GlyphBuffer, lookup: ReverseChainingSingleSubstLookup): void; /** Match Context Format 1 - glyph-based rules */ declare function matchContextFormat1(font: Font, buffer: GlyphBuffer, startIndex: number, subtable: ContextSubstFormat1, lookupFlag: number): SequenceLookupRecord[] | null; /** Match Context Format 2 - class-based rules */ declare function matchContextFormat2(font: Font, buffer: GlyphBuffer, startIndex: number, subtable: ContextSubstFormat2, lookupFlag: number): SequenceLookupRecord[] | null; /** Match Context Format 3 - coverage-based */ declare function matchContextFormat3(font: Font, buffer: GlyphBuffer, startIndex: number, subtable: ContextSubstFormat3, lookupFlag: number): boolean; /** Match Chaining Context Format 1 - glyph-based rules */ declare function matchChainingFormat1(font: Font, buffer: GlyphBuffer, startIndex: number, subtable: ChainingContextFormat1, lookupFlag: number): SequenceLookupRecord[] | null; /** Match Chaining Context Format 2 - class-based rules */ declare function matchChainingFormat2(font: Font, buffer: GlyphBuffer, startIndex: number, subtable: ChainingContextFormat2, lookupFlag: number): SequenceLookupRecord[] | null; /** Match Chaining Context Format 3 - coverage-based */ declare function matchChainingFormat3(font: Font, buffer: GlyphBuffer, startIndex: number, subtable: ChainingContextFormat3, lookupFlag: number): boolean; declare function applyNestedLookups(_font: Font, buffer: GlyphBuffer, startIndex: number, lookupRecords: Array<{ sequenceIndex: number; lookupListIndex: number; }>, plan: ShapePlan): void; /** * Glyph class cache for efficient repeated lookups during GPOS positioning. * Map from GlyphId to GlyphClass (avoids repeated GDEF lookups for same glyph). */ type GlyphClassCache = Map; declare function applyGposLookup(font: Font, buffer: GlyphBuffer, lookup: AnyGposLookup, plan: ShapePlan, glyphClassCache: GlyphClassCache, baseIndexArray: Int16Array, hasMarks: boolean): void; declare function applySinglePosLookup(font: Font, buffer: GlyphBuffer, lookup: SinglePosLookup, hasMarks: boolean): void; declare function applyPairPosLookup(font: Font, buffer: GlyphBuffer, lookup: PairPosLookup, hasMarks: boolean): void; declare function applyCursivePosLookup(font: Font, buffer: GlyphBuffer, lookup: CursivePosLookup, hasMarks: boolean): void; declare function applyMarkBasePosLookup(font: Font, buffer: GlyphBuffer, lookup: MarkBasePosLookup, glyphClassCache: GlyphClassCache, baseIndexArray: Int16Array): void; declare function applyMarkLigaturePosLookup(font: Font, buffer: GlyphBuffer, lookup: MarkLigaturePosLookup, glyphClassCache: GlyphClassCache, baseIndexArray: Int16Array): void; declare function applyMarkMarkPosLookup(font: Font, buffer: GlyphBuffer, lookup: MarkMarkPosLookup, glyphClassCache: GlyphClassCache): void; declare function applyContextPosLookup(font: Font, buffer: GlyphBuffer, lookup: ContextPosLookup, plan: ShapePlan, glyphClassCache: GlyphClassCache, baseIndexArray: Int16Array, hasMarks: boolean): void; declare function applyChainingContextPosLookup(font: Font, buffer: GlyphBuffer, lookup: ChainingContextPosLookup, plan: ShapePlan, glyphClassCache: GlyphClassCache, baseIndexArray: Int16Array, hasMarks: boolean): void; /** Match Context Pos Format 1 - glyph-based rules */ declare function matchContextPosFormat1(font: Font, buffer: GlyphBuffer, startIndex: number, subtable: ContextPosFormat1, lookupFlag: number): PosLookupRecord[] | null; /** Match Context Pos Format 2 - class-based rules */ declare function matchContextPosFormat2(font: Font, buffer: GlyphBuffer, startIndex: number, subtable: ContextPosFormat2, lookupFlag: number): PosLookupRecord[] | null; /** Match Context Pos Format 3 - coverage-based */ declare function matchContextPosFormat3(font: Font, buffer: GlyphBuffer, startIndex: number, subtable: ContextPosFormat3, lookupFlag: number): boolean; /** Match Chaining Context Pos Format 1 - glyph-based rules */ declare function matchChainingContextPosFormat1(font: Font, buffer: GlyphBuffer, startIndex: number, subtable: ChainingContextPosFormat1, lookupFlag: number): PosLookupRecord[] | null; /** Match Chaining Context Pos Format 2 - class-based rules */ declare function matchChainingContextPosFormat2(font: Font, buffer: GlyphBuffer, startIndex: number, subtable: ChainingContextPosFormat2, lookupFlag: number): PosLookupRecord[] | null; /** Match Chaining Context Pos Format 3 - coverage-based */ declare function matchChainingContextPosFormat3(font: Font, buffer: GlyphBuffer, startIndex: number, subtable: ChainingContextPosFormat3, lookupFlag: number): boolean; /** Apply nested positioning lookups at specific positions */ declare function applyNestedPosLookups(font: Font, buffer: GlyphBuffer, startIndex: number, lookupRecords: PosLookupRecord[], plan: ShapePlan, glyphClassCache: GlyphClassCache, baseIndexArray: Int16Array, hasMarks: boolean): void; /** Match a sequence of specific glyphs forward */ declare function matchGlyphSequence(font: Font, buffer: GlyphBuffer, startPos: number, glyphs: GlyphId[], lookupFlag: number): boolean; /** Match a sequence of specific glyphs backward */ declare function matchGlyphSequenceBackward(font: Font, buffer: GlyphBuffer, startPos: number, glyphs: GlyphId[], lookupFlag: number): boolean; /** Match a sequence of classes forward */ declare function matchClassSequence(font: Font, buffer: GlyphBuffer, startPos: number, classes: number[], classDef: ClassDef, lookupFlag: number): boolean; /** Match a sequence of classes backward */ declare function matchClassSequenceBackward(font: Font, buffer: GlyphBuffer, startPos: number, classes: number[], classDef: ClassDef, lookupFlag: number): boolean; declare function shouldSkipGlyph(font: Font, glyphId: GlyphId, lookupFlag: number): boolean; declare function applyMorx(font: Font, buffer: GlyphBuffer): void; export declare const __testing: { applyGsub: typeof applyGsub; applyGsubLookup: typeof applyGsubLookup; applyGposLookup: typeof applyGposLookup; applySingleSubstLookup: typeof applySingleSubstLookup; applyMultipleSubstLookup: typeof applyMultipleSubstLookup; applyAlternateSubstLookup: typeof applyAlternateSubstLookup; applyLigatureSubstLookup: typeof applyLigatureSubstLookup; applyContextSubstLookup: typeof applyContextSubstLookup; applyChainingContextSubstLookup: typeof applyChainingContextSubstLookup; applyReverseChainingSingleSubstLookup: typeof applyReverseChainingSingleSubstLookup; applySinglePosLookup: typeof applySinglePosLookup; applyPairPosLookup: typeof applyPairPosLookup; applyCursivePosLookup: typeof applyCursivePosLookup; applyMarkBasePosLookup: typeof applyMarkBasePosLookup; applyMarkLigaturePosLookup: typeof applyMarkLigaturePosLookup; applyMarkMarkPosLookup: typeof applyMarkMarkPosLookup; applyContextPosLookup: typeof applyContextPosLookup; applyChainingContextPosLookup: typeof applyChainingContextPosLookup; matchContextFormat1: typeof matchContextFormat1; matchContextFormat2: typeof matchContextFormat2; matchContextFormat3: typeof matchContextFormat3; matchChainingFormat1: typeof matchChainingFormat1; matchChainingFormat2: typeof matchChainingFormat2; matchChainingFormat3: typeof matchChainingFormat3; matchContextPosFormat1: typeof matchContextPosFormat1; matchContextPosFormat2: typeof matchContextPosFormat2; matchContextPosFormat3: typeof matchContextPosFormat3; matchChainingContextPosFormat1: typeof matchChainingContextPosFormat1; matchChainingContextPosFormat2: typeof matchChainingContextPosFormat2; matchChainingContextPosFormat3: typeof matchChainingContextPosFormat3; matchGlyphSequence: typeof matchGlyphSequence; matchGlyphSequenceBackward: typeof matchGlyphSequenceBackward; matchClassSequence: typeof matchClassSequence; matchClassSequenceBackward: typeof matchClassSequenceBackward; shouldSkipGlyph: typeof shouldSkipGlyph; precomputeSkipMarkers: typeof precomputeSkipMarkers; buildNextNonSkipArray: typeof buildNextNonSkipArray; applyNestedLookups: typeof applyNestedLookups; applyNestedPosLookups: typeof applyNestedPosLookups; applyMorx: typeof applyMorx; }; export {};