import { StrokeStyle, VectorPath } from '../vector.js'; /** A path drawn by the metafile: filled, stroked, or both. */ export interface PicturePath { readonly kind: 'path'; readonly paths: ReadonlyArray; /** 6-hex, no leading `#`. Absent when the path is not filled. */ readonly fillColorHex?: string; readonly stroke?: StrokeStyle; } /** A run of text the metafile puts at a point, in its own logical units. */ export interface PictureText { readonly kind: 'text'; readonly text: string; /** The reference point, in logical units (y DOWN, as the metafile has it). */ readonly x: number; readonly y: number; /** Which corner of the text the point names (MS-WMF §2.1.2.4 TextAlignment). */ readonly alignH: 'left' | 'center' | 'right'; /** Whether `y` is the text's TOP (the default) or its baseline. */ readonly alignBaseline: boolean; /** Em size in logical units — the height the font was created with. */ readonly sizeLu: number; readonly colorHex: string; readonly fontFamily?: string; readonly bold?: boolean; readonly italic?: boolean; /** Tenths of a degree, counter-clockwise — the font's own escapement. */ readonly escapement?: number; } /** A bitmap the metafile blits into a rectangle of its own logical frame. */ export interface PictureImage { readonly kind: 'image'; /** The destination rectangle in logical units (y down). */ readonly x: number; readonly y: number; readonly width: number; readonly height: number; /** The bitmap as a standalone file (PNG), ready for the resource store. */ readonly png: Uint8Array; } export type PicturePrim = PicturePath | PictureText | PictureImage; /** * One metafile, read: its primitives and the logical box they are drawn in. * Coordinates are the metafile's own, with y running DOWN; the caller maps the * box onto the picture's frame. */ export interface MetaPicture { readonly left: number; readonly top: number; readonly width: number; readonly height: number; readonly prims: ReadonlyArray; /** Records the reader knew of but did not draw, for a loss note. */ readonly skipped: ReadonlyArray; } /** A pen, a brush and a font, as the device context holds them. */ export interface MetaPen { readonly kind: 'pen'; readonly colorHex: string; readonly widthLu: number; readonly style: 'solid' | 'dash' | 'dot' | 'dashdot' | 'dashdotdot' | 'none'; } export interface MetaBrush { readonly kind: 'brush'; readonly colorHex: string; /** `null` for BS_HOLLOW/BS_NULL — a brush that paints nothing. */ readonly hollow: boolean; } export interface MetaFont { readonly kind: 'font'; readonly heightLu: number; readonly family?: string; readonly bold?: boolean; readonly italic?: boolean; readonly escapement?: number; } /** * An object the reader does not model — a palette, a region, a pattern brush. * It still OCCUPIES a slot in the metafile's object table: handles are indices * into that table, so a creation the reader passed over silently shifted every * one that followed. 23884's chart selects its coloured pens by handle, and one * unrecorded palette put every selection one slot back — on the black pen the * pens had displaced. */ export interface MetaOther { readonly kind: 'other'; } export type MetaObject = MetaPen | MetaBrush | MetaFont | MetaOther; /** The device context: everything a record draws THROUGH. */ export interface DeviceContext { pen: MetaPen; brush: MetaBrush; font?: MetaFont; textColorHex: string; bkColorHex: string; /** MS-WMF §2.1.1.9 — TRANSPARENT leaves the background of text unpainted. */ bkOpaque: boolean; alignH: 'left' | 'center' | 'right'; alignBaseline: boolean; fillRule: 'nonzero' | 'evenodd'; x: number; y: number; /** The world→page transform, as `[a, b, c, d, e, f]`. */ transform: readonly [number, number, number, number, number, number]; /** * MS-EMF §2.3.2 / MS-WMF §2.3.2 — the region drawing is limited to, in * logical units, when the metafile states a RECTANGULAR one. A primitive * that falls wholly outside it is not drawn: an embedded workbook's preview * clips its sheet to the used range, and unclipped we painted the whole * empty grid around it. */ clip?: { readonly left: number; readonly top: number; readonly right: number; readonly bottom: number; }; } export declare const DEFAULT_PEN: MetaPen; export declare const DEFAULT_BRUSH: MetaBrush; /** A device context in its documented initial state (MS-WMF §3.1.5). */ export declare function newDeviceContext(): DeviceContext; export declare function cloneDc(dc: DeviceContext): DeviceContext; /** * Whether a primitive bounded by `box` is wholly outside the device context's * clip. Partial overlaps are kept whole — the reader discards what the clip * excludes rather than cutting geometry, which is a missing cut, never wrong * content. * * @param dc The device context, for its clip. * @param box The primitive's bounds in logical units. * @returns `true` when nothing of it would be drawn. */ export declare function clippedAway(dc: DeviceContext, box: { left: number; top: number; right: number; bottom: number; }): boolean; /** The intersection of a device context's clip with another rectangle. */ export declare function intersectClip(dc: DeviceContext, rect: { left: number; top: number; right: number; bottom: number; }): NonNullable; /** * A primitive's bounds in the units it is stored in, for the clip test. * * @param prim The primitive. * @returns Its bounding rectangle; a text run's is its reference point, since * the box it fills is not known until it is measured. */ export declare function primBounds(prim: PicturePrim): { left: number; top: number; right: number; bottom: number; }; /** A COLORREF (`0x00bbggrr`) as the 6-hex this codebase's colours use. */ export declare function colorRef(v: number): string; /** Apply the world transform to a point. */ export declare function applyTransform(t: DeviceContext['transform'], x: number, y: number): { x: number; y: number; };