/** * Kashida justification (#375, arabic-typography §3). A justified line of * Arabic text is not letter-spaced (its letters join); it is stretched in * its word spaces and by elongating joins inside words, with tatweels * (U+0640, ـ) inserted between two connected letters. Fonts draw a run of * them as one stroke (Amiri's `rlig` turns one to seven into a curved * kashida of that length), so a kashida comes in whole tatweels. * * Two stages: * - Breaking: each Arabic word box carries its kashida capacity as stretch * (`kashidaCapacity`: points × the longest elongation a point may take), * so Knuth–Plass knows a line of Arabic words can widen there and picks * its breaks accordingly. * - Setting (`justifyLinesWithKashida`): once the breaks are made, every * justified line but the last fills its slack with tatweels first — one * whole tatweel at a time, best points first, round after round, each * word measured again whole with its tatweels — and leaves the remainder, * less than one tatweel, to its word spaces, which renderers widen as on * any justified line. So the word spaces keep close to their natural * width, the Naskh norm. * * Where the points are and how good they are: `kashidaPatterns.ts` (the * raqim-kashida rules). One point per word by default (`perWord`), the * best-ranked one, the later of two that rank alike ("towards the end of * the word", the Microsoft rule). A word holding a tatweel the author typed * is elongated there and nowhere else. * * The inserted tatweels are in the segment's text, so every renderer paints * them as text, shaped with the word; `VDTLineSegment.kashida` lists where * they are, so plain text, source maps, links and extraction leave them out * (`writtenText`), and `VDTLine.kashida` counts them. */ import type { VDTLine, VDTLineSegment } from '../vdt.js'; import { type KashidaPatternSetName } from './kashidaPatterns.js'; import type { ResolvedBodyTextConfig } from '../types.js'; export declare const TATWEEL = "\u0640"; /** Kashida justification as the measurer applies it * (`MeasureBlockOptions.kashida`). */ export interface KashidaOptions { patterns: KashidaPatternSetName; /** Most points elongated in one word. */ perWord: number; /** Longest elongation at one point, px (whole tatweels within it). */ maxLengthPx: number; } /** The pattern set a body font takes when `kashidaPatterns` is `'auto'`: * none for a Ruqʿa or Dīwānī face, whose letters do not elongate (Aref * Ruqaa); the Nastaʿlīq rules for a Nastaʿlīq face; Naskh otherwise. */ export declare function patternsForFont(fontFamily: string): KashidaPatternSetName | undefined; /** The measurer's kashida options for text set in `fontString` at * `fontSizePx` under `bodyText`, or `undefined` when it takes none * (kashida off, or a face whose letters do not elongate). */ export declare function kashidaMeasureOptions(bodyText: Pick, fontString: string, fontSizePx: number): KashidaOptions | undefined; /** A point chosen in a word: where the tatweels go (UTF-16 offset in the * word as written) and its rank. */ interface ChosenPoint { offset: number; priority: number; } /** The points of `word` that take its kashidas, best first: at most * `perWord`, ranked by priority and, between equals, the later one. A word * with a tatweel the author typed takes it alone (after the run it * starts). */ export declare function chosenKashidaPoints(word: string, patterns: KashidaPatternSetName, perWord: number): readonly ChosenPoint[]; /** How far kashidas can widen a word (px): its points times the whole * tatweels one point may take, `tatweelPx` each. 0 for a word with no * point (Latin, digits, a lone letter). The breaker's stretch of the * word's box. */ export declare function kashidaCapacity(word: string, options: KashidaOptions, tatweelPx: number): number; /** A segment's text as written: its text without the tatweels kashida * justification inserted (see `VDTLineSegment.kashida`). */ export declare function writtenText(seg: Pick): string; /** * Fill `width` px of slack on a line's segments with kashidas: whole * tatweels, one at a time, the best points first and round after round (a * second tatweel on a point only once every point that could take one has * one), each word measured again whole (`widthOf`) after each, and none * that would overfill the slack. Returns the segments (copies where * elongated) and how many tatweels went in, or null when none did. */ export declare function distributeKashida(segments: readonly VDTLineSegment[], width: number, options: KashidaOptions, widthOf: (seg: VDTLineSegment, text: string) => number): { segments: VDTLineSegment[]; added: number; count: number; } | null; /** * Kashida justification of a paragraph's lines (see the module comment): * every justified line but the last one, with its slack against * `lineWidth(i)` (the measure less its indent), takes its kashidas, then * its word spaces are measured again (`justifiedSpaceRatio`). A line whose * spaces would still stretch past the point where the pipeline sets it * ragged (`raggedLooseLines`) is left as it is, ragged lines take none. * Lines are replaced, never mutated. */ export declare function justifyLinesWithKashida(lines: VDTLine[], lineWidth: (index: number) => number, normalSpaceWidth: number, options: KashidaOptions, widthOf: (seg: VDTLineSegment, text: string) => number): void; export {}; //# sourceMappingURL=kashida.d.ts.map