/** * Bitmap text layout — turns a string into a list of coloured pixels. * * Aseprite's Lua API has no text rasteriser, so this runs entirely on the TS * side: `draw` op kind `text` calls `layoutText` and hands the result to * Aseprite as an ordinary `pixels` op, in the same transaction and under the * same palette lock as everything else in the batch (see ADR-0005). * * All layout maths happens in *font-grid units* — one cell per glyph column — * and only expands to output pixels (via `scale`) at the very end. Doing bold * growth and outline neighbour-checks at grid resolution, before the * nearest-neighbour blow-up, is what keeps a scaled letter's stroke weight * proportional instead of a 1px sliver lost in a 4x scale-up. */ export interface Font { name: string; license: string; cellWidth: number; cellHeight: number; /** Rows from the top of the cell down to and including the baseline row. */ baseline: number; spaceWidth: number; glyphs: Record; advance?: Record; } export type TextAnchor = "top_left" | "top" | "top_right" | "left" | "center" | "right" | "bottom_left" | "bottom" | "bottom_right" | "baseline_left" | "baseline" | "baseline_right"; export interface TextPixel { x: number; y: number; color: string; } export interface Bounds { x: number; y: number; width: number; height: number; } export interface LayoutTextOptions { text: string; x: number; y: number; color: string; font: Font; anchor?: TextAnchor; letterSpacing?: number; lineSpacing?: number; bold?: number; outlineColor?: string; outlineDiagonals?: boolean; shadowColor?: string; shadowOffset?: { x: number; y: number; }; scale?: number; } export interface TextLayout { pixels: TextPixel[]; /** Tight bounding box of the glyph ink alone — never outline or shadow. */ inkBounds: Bounds | null; } /** * Resolve `knowledge/fonts/.json` relative to the package root, the * same way `palette.ts` resolves `knowledge/palettes.json`. */ export declare function loadFont(name: string): Font; /** * Lay out `text` (multiline via "\n") against `font` and return every pixel * that should be written, plus the tight ink bounding box used for anchoring. * * Outline and shadow are decorative layers computed from the glyph ink after * `bold` growth, but never move it and never enter `inkBounds` — anchoring a * label by its ink, then turning on an outline, must not shift the label. */ export declare function layoutText(opts: LayoutTextOptions): TextLayout;