/** * A memo of whole frame layouts for one layout of a composed page (#972). * * The reflow ladder (#858) lays the page again at every step, and most * frames come out of a step as they went into it: the same story cut, at * the same width and height, in the same style, round the same * rectangles. `layoutRange` (the box typesetter, `frameLayout.ts`) asks * this memo before it lays such a range out and gets a copy of the earlier * result. The measurement memo (#953) already spares the measuring; what * is left is the placing, and the splitting probes, which lay the same * ranges the frame's final layout then needs. * * The memo lives as long as one `layoutComposedPage` run, as the * measurement memo does: what a layout reads besides its arguments (the * boxes that left the flow, a block's numbers, the page's column height) * is fixed only within the run. * * A caller that goes on to move the result (the frame's commit shifts it * to the page) gets a private deep copy; a caller that only reads it (the * splitting probes) gets the stored one. The copy keeps what the layout * keeps by identity (the designed headings of boxes, the end indent of a * block) and a layout that holds anything the copy cannot reproduce (a * comic page, with its own registries; a class instance) is never kept. * A layout writes to the measure context too (the drop cap notes and the * joining-script marks); those writes are recorded with the entry and * replayed on a hit, so the context ends up as if the range had been laid * out again. */ import type { ResolvedCalloutStyleConfig } from '../types.js'; import { type CalloutLayoutResult } from './calloutLayout.js'; import type { BlockMeasureContext, DropCapNote } from './measureContentBlock.js'; type NoteWrite = readonly [kind: 'set', block: number, note: DropCapNote] | readonly [kind: 'delete', block: number]; interface LayoutEntry { /** `kept`: `result` holds the layout; `never`: it cannot be copied. */ state: 'kept' | 'never'; /** The layout as it came out, before anyone moved it. */ result: CalloutLayoutResult | null; notes: NoteWrite[]; joined: number[]; } export interface LayoutMemo { readonly ids: WeakMap; next: number; /** Box styles by content: the ladder resolves a frame's style again on * every composition, so two layouts in equal styles hold two objects. */ readonly styles: Map; readonly styleOf: WeakMap; readonly entries: Map; /** Set while a layout is being recorded: a layout asked for from inside * one is laid out without the memo. */ recording: boolean; hits: number; misses: number; } /** Off only in tests, which lay a page both ways and compare. */ export declare const layoutMemoSwitch: { enabled: boolean; hits: number; }; export declare function createLayoutMemo(): LayoutMemo; /** What a layout of a range reads (see `makeCalloutLayouter`): where it * stands in the pass, the box style, the cut, the width, the frame's * options and the measuring state. */ export declare function layoutKey(memo: LayoutMemo, pass: object, ctx: BlockMeasureContext, startIdx: number, endIdx: number, style: ResolvedCalloutStyleConfig, from: unknown, to: unknown, width: number, frameId: string, continuation: boolean, mirrored: boolean, frame: unknown): string; /** A private copy of a layout, `null` when it holds what a copy cannot * reproduce. */ export declare function copyLayout(result: CalloutLayoutResult): CalloutLayoutResult | null; /** Lay out through the memo. `shared`: the caller only reads the result * and may be given the stored one. */ export declare function memoLayout(memo: LayoutMemo, key: string, ctx: BlockMeasureContext, shared: boolean, compute: () => CalloutLayoutResult): CalloutLayoutResult; export {}; //# sourceMappingURL=layoutMemo.d.ts.map