import { type Body } from './shapes.js'; import type { LetteringDiagnostic, LetteringForeignArt, LetteringPanel, LetteringPosition, PanelSide, Point, Rect } from './types.js'; /** One way to lay out a unit (a balloon, or a group of joined balloons): * its bodies relative to the unit's anchor (the first body's centre). */ export interface UnitVariant { bodies: Body[]; /** Whether this variant reshapes the text (a fallback). */ reshaped: boolean; /** Union of the bodies' boxes, relative. */ bbox: Rect; /** Points standing for the bodies (outline and inside), relative. */ samples: Point[]; /** Outline points of the bodies, relative (the outside test). */ rim: Point[]; /** Rotation of a sound effect, degrees (its box is the rotated one). */ rotate?: number; /** Lean of a sound effect's letters, degrees (applied before `rotate`). */ skew?: number; /** What the variant costs as it reads: a joined balloon set back, * against the reading direction, reads out of order; a reshaped text * that parts its words or phrases worse than the preferred shape. */ cost?: number; } /** Where a unit's tail aims, as placement sees it. */ export type TargetSpec = { kind: 'none'; } | { kind: 'point'; point: Point; } | { kind: 'offPanel'; toward?: Point; side?: PanelSide; }; /** A unit to place. */ export interface PlaceUnit { id: string; order: number; kind: 'balloon' | 'caption' | 'sfx' | 'note'; variants: UnitVariant[]; target: TargetSpec; pin?: Point; position?: LetteringPosition; butt?: boolean; breakBorder?: boolean; /** The item range for diagnostics. */ sourceStart: number; sourceEnd: number; /** A point of the art a sound effect goes to (the `sfx` anchor). */ near?: Point; /** The speaker (an anchor id): whose figure the unit may cover at the * lesser cost. */ speaker?: string; em: number; } /** The outcome for one unit. */ export interface Placed { unit: PlaceUnit; variant: number; at: Point; } interface Scene { panel: LetteringPanel; visible: Point[]; visBox: Rect; faces: Rect[]; avoid: (Rect & { guard?: boolean; })[]; /** Regions better left uncovered (the picture's safe area when the art * marks nothing else): a cost per area covered, never a fault. A * figure's zone (`owner`) costs {@link OTHER_FIGURE} times as much under * a balloon of another speaker, and under every balloon when it touches * another figure's (`contact`: arms around the other one). */ soft: (Rect & { weight?: number; owner?: string; contact?: boolean; })[]; mouths: Point[]; fwd: 1 | -1; /** The other panels' boxes. */ neighbours: Rect[]; /** The panels laid over this one (insets): theirs, not this panel's. */ over: (readonly Point[])[]; /** The page's live area. */ limit?: Rect; /** How far a balloon / a sound effect breaking its border on purpose * may run (the trim less the inset; the trim and the panel's bleed). */ edge?: Rect; edgeSfx?: Rect; /** Whether the panel runs past the live area (it bleeds): a `break` * balloon of a panel that does not keeps inside the live area. */ bleeds: boolean; /** Other panels' balloons, their tails as drawn, and what the other * panels' pictures protect (#671). */ foreign: (Rect & { round?: boolean; })[]; foreignTails: (readonly [Point, Point])[]; foreignArt: LetteringForeignArt[]; /** Never covered (the fold of a spread). */ keepOut: Rect[]; /** The panel's polygon inside the live area (see {@link livePolygon}). */ live: Point[]; /** What a butted caption sits flush against: the panel's polygon, inset * by half its border (the caption's outline then lies on the border). */ buttPoly: Point[]; /** Multiplier of the height preference (see `HEIGHT_BIASES`). */ heightBias?: number; } /** The part of a panel lettering may use: its polygon, less what runs * past the page's live area (a bleeding panel's art reaches the edge of * the sheet; its lettering stays where the trim cannot cut it). */ export declare function livePolygon(panel: Pick): Point[]; /** The border point an off-panel tail runs to: toward a cropped anchor, * on a named side, else the nearest border point. */ export declare function offPanelPoint(panel: LetteringPanel, centre: Point, toward?: Point, side?: PanelSide): Point; /** The anchor a corner or edge keyword puts a unit at: its box flush * with the panel (`butt`) or with the inset area, at that corner. */ export declare function positionAnchor(scene: Pick, v: UnitVariant, position: LetteringPosition, butt: boolean, along?: number): Point; /** The result of placing a panel's units. */ export interface PlacementResult { placed: (Placed & { level: number; })[]; diagnostics: LetteringDiagnostic[]; } /** * A placed layout with its crossed tails undone: pairs of balloons whose * tails cross (or all but touch) trade places or are placed again, each * seeing the other's tail, as long as the whole layout gets cheaper. What * {@link placeUnits} runs between its improvement passes, on its own. */ export declare function uncrossTails(panel: LetteringPanel, placed: readonly Placed[]): Placed[]; /** Place every unit of a panel (see the module comment). `extend`, when * given, adds spare variants to the units (see `letterPanelDetailed`): * a panel the first search leaves with a fault is searched again with * them, and the cheaper layout is kept. */ export declare function placeUnits(panel: LetteringPanel, units: readonly PlaceUnit[], passes?: number, extend?: () => boolean): PlacementResult; export {}; //# sourceMappingURL=placement.d.ts.map