/** * Vertical text on the canvas (`VDTPage.flow`). * * `paintPage` paints a vertical page's flow through the page's frame — the * context turned a quarter turn clockwise (`ctx.transform(0, 1, -1, 0, W, * 0)`) — and switches the painter here on for as long as it does. Every * text painter of the backend calls {@link fillFlowText} instead of * `ctx.fillText`: on a horizontal page it IS `ctx.fillText`, with the same * arguments; inside a vertical flow it cuts the text into sideways runs * (Latin, numbers: painted as they are, which the frame turns sideways) and * cells (Han, punctuation, dashes, upright symbols), each cell its length * down the line (one em; half an em for the mainland interpunct), the * character turned back to stand upright about the cell's centre on the * font's central axis (`VDTFlowFrame.centralBaselines`). The runs are the * ones the text was measured with (`verticalRuns`), so each segment paints * within the width the layout gave it. * * Punctuation takes the font's vertical form (OpenType `vert`) through a * twin face the host registers with {@link registerVerticalAlternates} — * the same font file loaded under another family name with * `featureSettings: '"vert" 1, "fwid" 1'`, which Chrome 140+ applies to * canvas text. Without a twin, the fallbacks of `verticalOrientation` * apply: brackets and quotes turned about the em box's centre, mainland * pause and stop marks and Japanese small kana moved to the upper right of * the cell (each by its glyph's `offset`); so do they where the twin has * no vertical form for the character. A dash, an ellipsis or a wave dash stands in the * twin's vertical form when the font has one (Noto CJK's —— needs `fwid` * with `vert`: a rule down the middle of the cell), else it is turned * with its ink centred on the column's axis. */ import type { CjkRegion } from '../types.js'; import { type ForcedOrientation } from '../writingMode.js'; import { type MarkCutRule } from '../measure/markCuts.js'; /** What the painter needs while a vertical flow paints. */ export interface VerticalPaintState { region: CjkRegion; /** `VDTFlowFrame.centralBaselines` of the page. */ axes?: Record; /** `cjk.uprightDigits`: a number of at most this many digits stands in * one upright cell (as the measurer found it, `verticalRuns`). */ uprightDigits?: number; } /** Switch vertical painting on (a state) or off (`null`); returns the state * it replaces, for the caller to put back. */ export declare function setVerticalPaint(state: VerticalPaintState | null): VerticalPaintState | null; /** Whether text painted now is set vertically. */ export declare function verticalPaintActive(): boolean; /** * How far the pen moves down the line for `text` painted now in the * context's font, as the layout measured it (`verticalTextWidth`): each * sideways run at the advance the context gives it, each cell at its * length in ems, `tracking` px after every character and every cell. * The context's `letterSpacing` is 0 (the tracking is counted here). * Undefined on a horizontal page. */ export declare function verticalFlowAdvance(ctx: CanvasRenderingContext2D, text: string, tracking: number): number | undefined; /** * Paint the vertical forms of `family`'s punctuation (brackets, quotes, * mainland pause marks, ellipses) with `twinFamily`: the same font loaded * under that name with `featureSettings: '"vert" 1'` (see * {@link loadVerticalAlternates}). Hosts that load fonts themselves call * this once the twin is ready; without one the painter's fallbacks apply. */ export declare function registerVerticalAlternates(family: string, twinFamily: string): void; /** Forget the twin of `family` (or of every family), removing the faces * {@link loadVerticalAlternates} added for it: the family's font changed * (a file uploaded again under the same name), so its twin must be loaded * again from the new sources. A load still under way for it is dropped. */ export declare function unregisterVerticalAlternates(family?: string): void; /** The twin family registered for `family`, if any. */ export declare function verticalAlternatesOf(family: string): string | undefined; /** The family name a twin of `family` is registered under by * {@link loadVerticalAlternates}. */ export declare function verticalTwinName(family: string): string; /** One face of a family: its source (a URL or the font bytes) and * descriptors, as `new FontFace` takes them. */ export interface VerticalAlternatesFace { source: string | ArrayBuffer; weight?: string; style?: string; unicodeRange?: string; } /** The characters a twin is loaded for (only these ever paint with it): * the brackets, quotes and pause marks, and the dashes, ellipses, wave * dashes, 〝〟, ー and small kana of Japanese text. A face cut into * `unicodeRange` slices (a Japanese web font has a hundred) loads the * slices that hold them, which a canvas does not wait for when it paints. */ export declare const VERTICAL_ALTERNATE_SAMPLE: string; /** * Load a twin of `family` with its vertical forms on (`featureSettings: * '"vert" 1'`) from the same sources, and register it when the browser * applies the feature to canvas text. The probe draws 「(《 with the twin * and with a copy of the same faces loaded without the feature, at the * weight and style of the faces the twin holds, and compares their ink; the * copy is removed afterwards. A twin whose faces leave the brackets as they * are (Chrome before 140 ignores `featureSettings` on canvas text) is not * registered, and the painter's fallbacks apply. Resolves to whether the * twin is in use. Browser only; a no-op (false) elsewhere. */ export declare function loadVerticalAlternates(family: string, faces: readonly VerticalAlternatesFace[]): Promise; /** How text is put on the canvas: filled, stroked (an outline), or both * (outline over the fill). */ export type TextPaintMode = 'fill' | 'stroke' | 'fillStroke'; /** * Paint `text` from `x` on `baseline`, as `ctx.fillText` would (and * `ctx.strokeText` for `mode` `'stroke'` / `'fillStroke'`). On a * horizontal page it is exactly those calls, except that two CJK marks * side by side that the layout measured apart are painted apart (see * `putHorizontal`); `cuts` says how the layout measured the text * (`MarkCutRule`: whole by default; word by word for a line of a Latin * paragraph; character by character for a line of the CJK composer). In a * vertical flow (see the module comment) it sets the text vertically: * `tracking` (px after every character, default the letter-spacing the * backend set on the context, `letterSpacingOf`) is added after each cell * and inside each sideways run. * Returns nothing; the caller advances by the width the layout measured. */ export declare function fillFlowText(ctx: CanvasRenderingContext2D, text: string, x: number, baseline: number, mode?: TextPaintMode, tracking?: number, cuts?: MarkCutRule, /** The orientation the author gave the text (`VDTLineSegment.tcy` / * `orientation`); vertical text only. */ orient?: ForcedOrientation): void; /** * Draw an image (or anything `draw` paints in a `w` × `h` box) inside a * box of the current frame: as is on a horizontal page; turned back to * stand upright on a vertical one, where the box's `w` runs down the sheet * and `h` across it. A box `sized` for that (`VDTDesignImageBlock.upright`: * its width is the picture's height) is filled; any other box was sized * for the picture's own proportions as if horizontal, which upright keep * them: scaled to fit the turned box, centred in it. */ export declare function drawUprightInBox(ctx: CanvasRenderingContext2D, x: number, y: number, w: number, h: number, draw: (x: number, y: number, w: number, h: number) => void, sized?: boolean): void; //# sourceMappingURL=verticalText.d.ts.map