import type { GPUVegaScene } from '../types/context.js'; /** The vertical translation canvas's rasterizer holds, per text mark, in device pixels. */ export type TextDrift = Map; /** * The translation canvas's rasterizer actually holds when each text mark draws, * against the one it reports, in device pixels. * * Chrome keeps a canvas matrix in float32 and reports it back as a double, and * vega's canvas renderer translates to every arc, shape, symbol and path item * and back again by the negated offset. Those cancel on paper and not in * float32, so the matrix drifts further from the reported one with every item * drawn: about 2.7e-4 of a pixel over the 2260 symbols of the `label` spec. * * That is nothing anywhere except across a tie. Canvas rounds a text baseline * to a whole device pixel and rounds an exact half up, so a baseline landing on * .5 goes up undrifted and down drifted, and the label moves a whole row. Four * labels in `label` sit on exactly .5 and all four are a row out. * * Walking the scene the way that renderer does and accumulating the same * float32 translation reproduces the number exactly: 10.999725341796875 where * the reported matrix says 11, which is what puts The Godfather on row 14 * rather than 15. * * Returns null when the scene holds something this does not model, which today * is a rotated item: vega rotates and unrotates around those, and that perturbs * the whole matrix rather than its translation. Placing text exactly is a * better answer than placing it by a drift we got wrong. */ export declare function canvasTextDrift(root: GPUVegaScene, origin: readonly number[], ratio: number): TextDrift | null;