/** * The CJK line composer: Chinese (and Japanese, Korean) paragraphs, on both * the plain and the formatted path, broken between characters under the * clreq prohibitions of the document's `cjk.lineBreak` and, when justified, * spread between characters. * * Linear in the paragraph: every unit (one grapheme, a Western run a line * never breaks inside, a 2-em dash or ellipsis, an atomic box) is measured * once — the width cache holds single characters, not prefixes — and the * breaker walks the units once with a running width. A line that would * start with a prohibited mark gives up characters to the next line * (push-out), back to the last break the rules allow. * * Justification (clreq §6.2.2.4): a justified line that is not its * paragraph's last is stretched to the measure — word spaces first, up to * ½ em each, then every gap between characters equally, never inside a * Western run (a word, a number with its signs), a 2-em dash or ellipsis, * and never next to a connector or a solidus. The spread is carried as * segment `tracking` (px after each grapheme, in the segment's width); a * Western run or a dash pair that a gap follows gives its last grapheme a * segment of its own. A line that needs more than the cap (½ em, or * `bodyText.maxJustifyTracking` when set) is set with the cap and flagged * `cjkLoose` and `ragged`; a line with no CJK character on it (the head of * a long web address) is set `ragged` without the flag. Japanese * full-width text (`isJlreqSpacing`) follows JLReq §3.8 instead where it * differs: a line takes one more character by giving up blank in Table 3's * order (`fitLine`), and is never spread inside a bracket or next to * 、。・?!, a hyphen or U+3000 (`gapStretches`, JLReq §3.1.11). * * Segments: a Western run keeps one of its own, and single characters * share one only when they have one style, link and spacing and advance * alike, so a caret spread evenly over a segment lands on its characters * and a Markdown link covers only its own. */ import type { InlineSpan } from '../parse/index.js'; import type { VDTSegmentMarks } from '../vdt.js'; import { type MeasuredBlock, type MeasureBlockOptions } from './types.js'; import { type CjkLineBreakLevel } from './cjkClasses.js'; import { type CjkComposition } from './cjkPunctuation.js'; /** * Whether a paragraph is set by the CJK composer: it holds more CJK letters * than word spaces. A word space is a run of spaces between two characters * that are not CJK. A space that touches a CJK character or mark is the * one web text types at each boundary (`2026 年 9 月 28 日`, `安装 Node.js * 和 Git`), which the composer replaces with the Han–Latin space. * A Latin paragraph that quotes a Chinese title or name ("the novel 紅樓夢 * was …") has more word spaces, stays with Knuth–Plass and breaks next to * the characters it quotes; a Chinese paragraph with Latin words in it * ("用 iPhone 拍照") is composed, with its typed spaces or without them. */ export declare function isCjkParagraph(text: string): boolean; /** Whether the CJK composer sets a paragraph of this text: it holds CJK * text (not only unit squares or marks Latin shares with Chinese) and more * CJK letters than word spaces (see {@link isCjkParagraph}). Both * measuring paths ask this, so they agree. */ export declare function composesAsCjk(text: string): boolean; /** * Whether the CJK composer sets a paragraph that is nothing but a row of * dashes (――――――, a rule the author typed between two passages): in a * Chinese or Japanese document it does (#680), so the row is drawn as one * rule (`routeSharedMarks`) where the word-by-word path would paint each * dash at its face's advance, a stroke per cell. The dashes alone say * nothing about the language ({@link composesAsCjk}); the document does. */ export declare function composesDashRow(text: string, c?: CjkComposition): boolean; /** The marks a span sets on its characters (#193, #421), the defaults * of what the span leaves unset filled in (`cjk.emphasisMark` has filled * the region's in already, `pipeline/annotations.ts`): emphasis dots a * filled dot (an open circle), a side line solid; both under the text, * or right of it in vertical text. */ export declare function spanMarks(span: InlineSpan, vertical: boolean): VDTSegmentMarks | undefined; /** * Set a Chinese, Japanese or Korean paragraph (see the module comment): * `options.cjkLineBreak` (else the document's level) decides where lines * may break; `textAlign: 'justify'` spreads every line but the last to the * measure. First-line and hanging indents, the block's tracking * (`letterSpacingPx`), other measures for later lines (`restWidths`) and a * positive `looseness` (one line more, for column balancing: the lines are * broken a little short of the measure and spread to it) are honoured; * Knuth–Plass options are not used. */ export declare function composeCjkParagraph(spans: InlineSpan[], normalFont: string, boldFont: string, italicFont: string, boldItalicFont: string, maxWidthPx: number, lineHeightPx: number, options: MeasureBlockOptions | undefined): MeasuredBlock; /** Where a word that holds CJK characters may break, and its widths: see * {@link cjkWordBreaks}. */ export interface CjkWordBreaks { /** Offsets into the word a line may break at, ascending. */ breaks: number[]; /** The word's advance: the sum of its units'. */ width: number; /** The advance of the word's first `idx` characters. */ widthBefore: (idx: number) => number; } /** * The breaks of one word (no breaking space inside) that holds CJK * characters, in a paragraph set by the word-by-word breaker (a Latin * paragraph quoting CJK): next to its CJK characters, under the document's * line-break rules. Each unit is measured once and the widths before a * break come from their running sums, so a long run of ideographs costs * linear time. With `keepAll` (`cjk.wordBreak: 'keep-all'`, or the block's * own rule) no break is left between two letters, as in a paragraph the * composer sets ({@link keepAllBreaks}): a quotation of a few characters * stays whole, and a break next to its punctuation stays where the level * allows it (#705). */ export declare function cjkWordBreaks(word: string, font: string, smallCaps: boolean | undefined, letterSpacingPx: number, level?: CjkLineBreakLevel, keepAll?: boolean): CjkWordBreaks; //# sourceMappingURL=cjkCompose.d.ts.map