/** * Figure labels drawn on their picture (#860, DESIGN §2.6, §3.3). * * A `:::figure` lists `::label[TEXT]{at style}` lines; the resource holds * the anchors (points in fractions of the whole picture, shared by every * locale). Each label is set as a small caption (inline Markdown: bold, * italic, chips, marks, references, formulas) in its label style, wrapped * within its anchor's `width` and, when a word is still too wide, set * smaller down to the style's `minScale`. Its box stands at the anchor's * point as `align` / `verticalAlign` say (start and end follow the label's * own direction), turned by `rotate` degrees about that point. * * The label's geometry is kept in its own frame (origin at the anchor * point) and the point itself relative to the picture's body, so the * label moves with its block wherever placement, frames, spreads or the * memo put it, and the painters only add the body's corner: * {@link figureLabelMatrix}. Once the pages exist the build stamps each * label's `rect` (for `sourceAt`) and reports the anchors a figure names * wrongly or leaves without a word ({@link figureLabelWarnings}). */ import type { InlineSpan } from '../parse/types.js'; import type { FigureLabel } from '../parse/types.js'; import type { LeaderStyle, Resource, ResourceAnchor, ResourceType } from '../types.js'; import type { BoundingBox, ContentWarning, ResolvedConfig, ResolvedResourceBlock, VDTBlock, VDTDesignBoxStyle, VDTDesignPathBlock, VDTDocument, VDTFigureLabel, VDTFigureLabelLayout, VDTPage, VDTLine } from '../vdt.js'; import type { MeasurementCache } from '../measure/index.js'; import type { ResourceNumberingMap } from '../pipeline/resourceNumbering.js'; /** `[a, b, c, d, e, f]`, canvas `transform` order (y down). */ export type LabelMatrix = [number, number, number, number, number, number]; /** A label style resolved for one label: the type and the plate. */ export interface LabelLook { styleId?: string; fontFamily: string; fontPx: number; weight: number; boldWeight: number; italic: boolean; color: string; uppercase: boolean; /** Ems. */ letterSpacing: number; lineHeight: number; halo?: { color: string; widthPx: number; }; background?: string; paddingPx: number; minScale: number; /** Set in vertical writing (the label style's; an anchor's wins). */ vertical?: boolean; /** How the lines line up inside the box (#1058); absent: as the anchor * places the box. */ align?: 'start' | 'center' | 'end'; /** The plate's outline and corners (#1058). */ border?: { color: string; widthPx: number; }; radiusPx?: number; /** A map's key (#1058): rows of symbol and text. */ legend?: boolean; /** The style's leader look (#1057), as written. */ leader?: LeaderStyle; } /** * The look of a label set in style `styleId` (the label's own `style`, * else its anchor's): the body text's type, under the paragraph style the * label style borrows (`paragraphStyle`), under the label style's own * fields. An unknown or absent style is the body text's type. */ export declare function resolveLabelLook(styleId: string | undefined, resolved: ResolvedConfig): LabelLook; /** Where a label stands on the picture: its anchor (looked up on the * resource) or its percentages, with the anchor's label fields. */ export interface LabelPlace { /** Fractions of the whole picture. */ x: number; y: number; anchor?: ResourceAnchor; } /** The place of `label` on `resource`; undefined when it names an anchor * the resource lacks. */ export declare function labelPlace(label: Pick, resource: Pick): LabelPlace | undefined; /** A point of the whole picture (fractions) in px from the top-left of the * body as drawn: through its crop (`bodySource`) and its size. */ export declare function pictureToBody(rb: Pick, fx: number, fy: number): { x: number; y: number; }; /** What laying the labels out needs besides the block. */ export interface FigureLabelContext { resolved: ResolvedConfig; resourceNumbering?: ResourceNumberingMap; resourceTypes?: ResourceType[]; resources?: Resource[]; cache?: MeasurementCache; } /** * The rows of a legend (#1058) with the symbol that opens each row hung in * one column: every such symbol's segment widened to the widest of them, * the symbol centred in it, so the words after them start at one edge. A * row with no symbol first is left as it is. The segments are copies: the * measured lines may be shared with a cache. */ export declare function hangLegendSymbols(lines: readonly VDTLine[]): VDTLine[]; /** * Lay out one label: its lines in its look, wrapped within `widthPx` (none: * one line per forced break), set smaller (down to `minScale`) while a * line is wider, then placed about the anchor point by `align` and * `verticalAlign`. */ export declare function layOutLabel(spans: readonly InlineSpan[], look: LabelLook, place: { x: number; y: number; widthPx?: number; align?: ResourceAnchor['align']; verticalAlign?: ResourceAnchor['verticalAlign']; rotate?: number; vertical?: boolean; }, ctx: FigureLabelContext): VDTFigureLabelLayout | undefined; /** * The labels of a figure laid out on its picture: `labels` (the VDT's, * `figureLabels`) with the `layout` of each one that can be drawn, read * from `parsed` (the parser's, the same order) for its inline Markdown. * A table, a video or a picture with no body draws none; a label whose * anchor is unknown is left without a layout. */ export declare function layOutFigureLabels(labels: readonly VDTFigureLabel[], parsed: readonly Pick[] | undefined, rb: ResolvedResourceBlock, ctx: FigureLabelContext): VDTFigureLabel[]; /** * The leader of a drawn label (#1057) as a path in the block's frame, the * body's top-left corner at (`bodyX`, `bodyY`), or undefined when it has * none or its point lies under the label's box. The line leaves the box * (its plate, else its lines' box, `gapPx` out) from the middle of the * side facing the point (the side with the wider clear gap to it), in the * label's own frame, so it never runs over the label's words, a turned * label's included; an elbow leaves that side square and turns once onto * the point. */ export declare function figureLabelLeaderPath(layout: VDTFigureLabelLayout, bodyX: number, bodyY: number): VDTDesignPathBlock | undefined; /** The leaders of a figure's drawn labels (#1057) in the block's frame, * the body's corner at (`bodyX`, `bodyY`), in the labels' order. */ export declare function figureLabelLeaderPaths(rb: Pick, bodyX: number, bodyY: number): VDTDesignPathBlock[]; /** * Where anchor `anchorId` of the picture of `block` (a figure laid on * `page`) stands on the page's sheet (#1057), through the picture's crop, * safe area and scale as its labels are: undefined when the block is no * picture or its resource lacks the anchor. A picture is painted the right * way round on a mirrored page and upright on a vertical one, so the point * is read on the body's box as the sheet shows it. */ export declare function figureAnchorPointOnPage(page: Pick, block: Pick, anchorId: string): { x: number; y: number; } | undefined; /** The matrix that puts a label's frame on the block's frame, the body's * top-left corner at (`bodyX`, `bodyY`): `translate(body + point) · * rotate(rotate)`. */ export declare function figureLabelMatrix(layout: Pick, bodyX: number, bodyY: number): LabelMatrix; /** A label's plate (#1058) as a design box's style, for the painters of * boxes: its fill, its outline drawn inside the plate, its corners. */ export declare function labelPlateBox(plate: NonNullable): VDTDesignBoxStyle; /** What a label paints in its own frame: its background, else its lines' * box. */ export declare function figureLabelExtent(layout: VDTFigureLabelLayout): BoundingBox; /** The upright box a label covers in the block's frame. */ export declare function figureLabelBounds(layout: VDTFigureLabelLayout, bodyX: number, bodyY: number): BoundingBox; /** The point `(x, y)` of the block's frame in a label's own frame. */ export declare function pointInLabel(layout: VDTFigureLabelLayout, bodyX: number, bodyY: number, x: number, y: number): { x: number; y: number; }; /** * Stamp `rect` on every drawn label of the document (#860): the upright * box it covers in its block's frame, through a quarter-turned block's * turn. A label not drawn loses any `rect` it had. */ export declare function stampFigureLabelRects(doc: VDTDocument): void; /** The spine of a spread sheet and the band the binding takes. */ export interface SpineBand { /** The band along the spread's axis: `lo` to `hi`, centred on the spine. */ lo: number; hi: number; spine: number; /** `'x'` on horizontal pages; `'y'` where the sheet runs down the flow (#926). */ axis: 'x' | 'y'; } /** * `block` with every label that reaches into the binding band moved off it * (#990). A figure across the spine of a spread paints its half on each * page, so a label whose box meets the band is cut by the fold and read * on neither page. Each such label slides along the spread to the side its * anchor point lies on (ties: the first page, as a frame's are) until its * box stands at the band's edge; an anchor that says `gutter: 'cross'` * keeps its place. The block comes back unchanged (the same object) when * no label moves, and a changed one is a copy: the labels of a measured * block may be shared with a cache. */ export declare function keepLabelsOffGutter(block: VDTBlock, band: SpineBand): VDTBlock; /** * The glyph of a drawn label under the point `(x, y)` of its block's * frame: the index into `label.text`'s source map, or undefined off its * lines. Lines are read from their plain ranges; a label whose lines lack * them spreads its text over its lines in order. */ export declare function labelGlyphAt(label: VDTFigureLabel, block: Pick, x: number, y: number): number | undefined; /** * A label layout for the flow of a mirrored page (a right-to-left book): * its point, its turn and its lines reflected about the body's vertical * axis, so that the page's reflection puts it back where the picture shows * it, reading as written. `bodyWidth` is the body's width; `orient` turns * a line's run order for the frame as the build does for captions. */ export declare function mirrorLabelLayout(layout: VDTFigureLabelLayout, bodyWidth: number, orient: (line: VDTLine) => VDTLine): VDTFigureLabelLayout; /** * The layout of a vertical label (`mirrored`) as it was set, before * {@link mirrorLabelLayout} reflected it for the flow of a mirrored page: * the geometry reflected back about the body's axis. The painters of such * a flow reflect their frame back about the body, so this layout lands on * the sheet where the label's anchor says, its cells running down the * column and standing upright, whatever the page's direction. */ export declare function unmirrorLabelLayout(layout: VDTFigureLabelLayout, bodyWidth: number): VDTFigureLabelLayout; /** * The layout of a label of a mirrored page (a right-to-left book) as it * stands on the sheet, for a renderer that does not paint through the * page's reflection (the SVG layer of a reflowable EPUB, #969): its point * and its lines reflected back about the body's axis, and the run order of * each line turned back, so `order` is the order of the segments from left * to right on the sheet. A vertical label comes back as * {@link unmirrorLabelLayout} gives it. A layout of a page that is not * mirrored must not be given: nothing marks one. */ export declare function labelLayoutOnSheet(layout: VDTFigureLabelLayout, bodyWidth: number): VDTFigureLabelLayout; /** The labels of a figure that are not drawn as text: what its picture's * alternative text still names (`altWithLabels`). */ export declare function undrawnLabels(labels: readonly VDTFigureLabel[] | undefined): VDTFigureLabel[] | undefined; /** A drawn label's words as read, its lines joined by a space (a legend's * rows by a semicolon), each inline symbol read as its alternative text * in brackets, or not at all when it has none (#1058). */ export declare function figureLabelReading(label: VDTFigureLabel): string; /** One line of a drawn label as read (see {@link figureLabelReading}). */ export declare function figureLabelLineReading(line: VDTLine): string; type Pt = [number, number]; /** How far two convex polygons run into each other: the shortest push that * frees them (separating axis test), 0 when they do not meet. */ export declare function polygonPenetration(a: readonly Pt[], b: readonly Pt[]): number; /** The pairs of labels whose lines meet: for each label (by index) the * indices of the earlier labels it meets. `allowed[i]` leaves label `i` * out: no pair it belongs to is reported (#977). */ export declare function overlappingLabels(labels: readonly Pick[], allowed?: readonly boolean[]): Map; /** * The symbols of the picture (its `avoid` zones, in fractions of the whole * picture) each label runs onto: for each label (by index) the 0-based * indices of the zones its lines or plate meet (#969). `allowed[i]` leaves * label `i` out. The zones are rectangles in the body's frame, through the * picture's crop, so a picture shown smaller or cropped to its safe area * moves them with the art. */ export declare function labelsOverSymbols(labels: readonly Pick[], zones: readonly NonNullable[number][], rb: Pick, allowed?: readonly boolean[]): Map; /** * The anchors the figures of `doc` name wrongly (`labelAnchorUnknown`, at * the label's text) or leave without a word (`anchorUnlabelled`, a note * at the figure: an anchor that names a label style and that no label of * the figure stands at), the labels that do not fit their measure * (`labelOverflow`) and those whose boxes meet (`labelOverlap`, #902), * each on the page its figure landed on. */ export declare function figureLabelWarnings(doc: VDTDocument, figureSource: (block: VDTBlock) => { start: number; end: number; } | undefined): ContentWarning[]; export {}; //# sourceMappingURL=labels.d.ts.map