import type { ForcedOrientation } from '../writingMode.js'; import type { InlineSpan } from '../parse/types.js'; import type { VDTChip } from '../vdt.js'; import type { ResolvedChipStyleConfig } from '../types.js'; import type { TextOverflow } from '../types.js'; /** One run of a design text line in its own font (see `VDTDesignTextRun`). */ export interface DesignTextRun { text: string; fontString: string; /** A contents part row's leader (see `VDTDesignTextRun.leader`). */ leader?: true; /** The run's own colour (see `VDTDesignTextRun.color`). */ color?: string; /** Advance of the run, tracking included. */ width: number; /** Script offset off the baseline (px, positive down). */ baselineShift?: number; /** The first of a subscript and a superscript set over each other: it * advances nothing (width 0) and the next run is painted at its x. */ stacked?: boolean; /** Vertical text: a run the author set in one upright cell (`:tcy[…]`). */ tcy?: true; /** Vertical text: a run the author stood upright (`:upright[…]`) or * turned (`:sideways[…]`). */ orientation?: 'upright' | 'sideways'; /** Painted right to left (see `VDTDesignTextRun.rtl`). */ rtl?: true; /** The run's `width` is its box, not its glyphs' advance: a CJK mark * that gave up blank, a space set at the Han–Latin width (#637). Its * glyphs are painted from `x + inkOffset` (see * `VDTDesignTextRun.inkOffset`). */ inkOffset?: number; /** A dash of a 破折号 stretched over its cell (#652): the scale its * glyph is painted at along the line (see * `VDTDesignTextRun.inkScale`). */ inkScale?: number; /** An inline chip (`:chip[…]`, #1162): the run is the chip's one * placeholder character, `width` its advance, and the box and its words * are painted from `chip` (see `VDTDesignTextRun.chip`). */ chip?: VDTChip; } /** The chips a design text may set (#1162): the document's chip styles * and what their boxes are resolved with. A text read without it keeps * `:chip[…]` as written. */ export interface DesignChipContext { styles: readonly ResolvedChipStyleConfig[]; dpi: number; /** The text's tracking, which the chip's words are measured with. */ letterSpacingPx: number; } interface RunStyle { font: string; /** The marks the style was made from (the CJK composer picks its fonts * by them, `design/cjkText.ts`); absent on the element's own. */ bold?: boolean; italic?: boolean; shift?: number; /** The script, for stacking a subscript and a superscript that touch; * `stackedShift` is a subscript's drop under a superscript. */ script?: 'sup' | 'sub'; stackedShift?: number; /** Vertical text: the orientation the author forced. Each `:tcy` span * has a style of its own, so two never merge into one cell. */ orient?: ForcedOrientation; /** The same style without the orientation (a hyphen or an ellipsis set * beside an oriented run takes it); for a chip, the style of the text * around it. */ base?: number; /** A chip's own style (one per chip): its laid-out box, its advance * and the span it was measured from (the CJK composer sets it again). */ chip?: VDTChip; chipWidth?: number; chipSpan?: InlineSpan; /** The chip style's gap (px) to a neighbour across a space. */ chipGap?: number; } /** A design text read for inline marks: its plain text (markers dropped) * and the style of every character. */ export interface RichDesignText { text: string; /** Index into `styles` of each character of `text`. */ styleAt: number[]; /** `styles[0]` is the element's own font. */ styles: RunStyle[]; /** Whether any character is set in a style other than the element's. */ hasMarks: boolean; } /** The element typography the runs derive from. */ export interface RichFontSpec { family: string; sizePx: number; weight: number; italic: boolean; } /** The fonts the runs of a design text with inline marks take: the * element's, bold (700, or the element's weight when heavier), italic * (the element's slant flipped) and both, as {@link parseRichDesignText} * picks them. */ export declare function richFontSet(spec: RichFontSpec): { normal: string; bold: string; italic: string; boldItalic: string; }; /** Read `text` for inline marks. Bold runs take weight 700 (the element's * own weight when it is heavier); italic runs flip the element's slant; * scripts use the body text's script size and shift. In vertical text * (`measuringVertically`) a run the author set with `:tcy`, `:upright` or * `:sideways` stands as the body sets it; horizontal text ignores the * marks. */ export declare function parseRichDesignText(text: string, spec: RichFontSpec, chips?: DesignChipContext): RichDesignText; /** The plain text of `text` read for inline marks: the markers dropped, * as `parseRichDesignText` sets it (a chip one placeholder character, * when the text reads chips). */ export declare function plainDesignText(text: string, chips?: boolean): string; /** The spans of `[a, b)` of a rich design text, one per change of style, * for the CJK composer (`design/cjkText.ts`): bold, italic, script and * orientation as the parser read them. */ export declare function richDesignSpans(rt: RichDesignText, a: number, b: number): InlineSpan[]; /** A laid-out line: its visible pieces in order (a hyphen or an ellipsis * is a piece of its own, in the style of the text beside it). */ type Piece = { text: string; style: number; }; export interface RichLine { text: string; width: number; runs: DesignTextRun[]; /** The line ends in a piece of a word wider than the line, cut at a * syllable or between two characters (#1150). */ wordDivided?: 'syllable' | 'character'; } /** Measuring and run building over one rich text. */ export declare class RichMeasurer { readonly rt: RichDesignText; readonly letterSpacingPx: number; /** How a run's text is measured, untracked, when not as any text of * the flow: in the direction its pieces are painted in, in a document * shaped in its own language (#770, `design/bidiText.ts`). */ private readonly flow?; constructor(rt: RichDesignText, letterSpacingPx: number, /** How a run's text is measured, untracked, when not as any text of * the flow: in the direction its pieces are painted in, in a document * shaped in its own language (#770, `design/bidiText.ts`). */ flow?: ((text: string, font: string) => number) | undefined); private widthOf; /** Whether `[k, k + 1)` lies inside a run the author oriented (a line * never breaks inside one, even at a space). */ insideOriented(k: number): boolean; /** The pieces of `[a, b)`, one per change of style. */ pieces(a: number, b: number): Piece[]; /** Width of `[a, b)` plus any extra pieces, as the runs will paint it: a * subscript and a superscript that touch advance as far as the wider. */ measure(a: number, b: number, ...extra: Piece[]): number; /** Character ranges `[start, end)` of `[a, b)` a line never ends inside: * the subscripts and superscripts set over each other, and in vertical * text the runs the author oriented (a `:tcy` cell, an `:upright` or * `:sideways` run). */ stackedRanges(a: number, b: number): [number, number][]; /** Style of the character at `i` (clamped to the text), for a hyphen or * an ellipsis set beside it: an oriented run's without its orientation. */ styleNear(i: number): number; /** A line from its pieces: adjacent pieces of one style merge into a run. */ line(pieces: Piece[]): RichLine; rangeLine(a: number, b: number, hyphen?: boolean): RichLine; } /** Greedy word wrap of one paragraph `[start, end)` (no newline inside), * line `i` being `widthFor(i)` wide. Leading spaces of the paragraph are * kept, trailing spaces of every line dropped; a word wider than a line * breaks by syllable (with `hyphenate`) or by character. */ export declare function wrapRich(m: RichMeasurer, start: number, end: number, widthFor: (i: number) => number, hyphenate: boolean, /** A justified text that hyphenates (EF-109): a word that does not fit * the rest of a line is cut at its last syllable break that does. */ fill?: boolean): RichLine[]; /** Where an `ellipsis-end` truncation of `text[from, to)` ends, given `fit` * — the end of the longest head that fits beside the ellipsis. The cut * moves back to the last word boundary, and the spaces and joining * punctuation before the ellipsis are dropped — unless what is left keeps * less than half of what fits (a single long word, a URL): then the word * is cut where it must, except a word of a joining script (Arabic), which * goes whole. Never past `fit`, so the head still fits. */ export declare function ellipsisEndCut(text: string, from: number, to: number, fit: number): number; /** Where an `ellipsis-start` truncation of `text[from, to)` starts, given * `fit` — the start of the longest tail that fits beside the ellipsis: the * mirror of `ellipsisEndCut`. Never before `fit`. */ export declare function ellipsisStartCut(text: string, from: number, to: number, fit: number): number; /** An `ellipsis-middle` truncation keeping `text[from, from + left)` and * `text[to - right, to)`, with the spaces that would touch the ellipsis * dropped, and neither side ending inside an Arabic word. */ export declare function ellipsisMiddleCut(text: string, from: number, to: number, left: number, right: number): { left: number; right: number; }; /** One explicit line `[s, e)` set on a single line: whole, clipped by the * renderer, or truncated with an ellipsis at `mode` (the cut placed by * `ellipsisEndCut` / `ellipsisStartCut` / `ellipsisMiddleCut`). */ export declare function singleRichLine(m: RichMeasurer, s: number, e: number, maxWidth: number, overflow: TextOverflow): RichLine; export {}; //# sourceMappingURL=richText.d.ts.map