/** * Box-filtered minification for canvases the browser would otherwise shrink * on its own. * * A canvas whose backing store is bigger than its CSS box is resampled by the * compositor with one bilinear tap: four source pixels out of every N², which * past 2:1 throws most of the image away and reads as nearest-neighbour — * dropped scanlines in a video surface, disintegrating stems in a glyph. * Nothing in CSS fixes it. There is no mip chain behind a canvas, and every * `image-rendering` value still samples at most four texels. * * Halving in Canvas2D does fix it: at exactly 2:1 a bilinear tap *is* the 2×2 * box average, so a chain of halves visits every source pixel. Reductions are * therefore quantised to powers of two, and the remainder — always under 2:1, * where one tap is the right filter — is left to CSS. Quantising also keeps * the picture stable while a pane is dragged: the chain only changes at * octave boundaries, not on every pixel of the drag. */ /** * How many halvings bring an `sw`×`sh` image down to at most `bw`×`bh`, * measured the way `object-fit: contain` measures it. 0 when it already fits, * so callers can treat "no reduction" as the ordinary 1:1 path. */ export declare function halvings(sw: number, sh: number, bw: number, bh: number): number; /** The extent an axis lands on after `n` halvings. Size the destination with * this so it matches what {@link drawHalved} writes. */ export declare function halve(extent: number, n: number): number; /** * Round an extent up to the next power of two, floored at 64. * * For asking someone else — a server encoder — for a size, where the cost of * changing your mind is far higher than the cost of overshooting. Snapping to * octaves means a drag re-asks a couple of times instead of on every pixel, * and the ≤2:1 overshoot lands exactly where {@link drawHalved} and a single * CSS tap clean it up for free. */ export declare function octaveCeil(extent: number): number; /** * A ResizeObserver entry's content box in the device pixels the compositor * will rasterise it at. Returns null for a zero-sized (detached, * display:none) box. * * Deliberately not `devicePixelContentBoxSize`, which looks like the exact * answer and is not always: under a headless browser's device-scale-factor * emulation it reports the CSS box unscaled, and believing it costs a whole * extra octave of reduction — a thumbnail blurrier than the one this module * exists to fix. `devicePixelRatio` is the ratio the layer is actually * rasterised with, and octave quantisation makes the sub-pixel precision * `devicePixelContentBoxSize` would buy irrelevant. */ export declare function devicePixelBox(entry: ResizeObserverEntry): { width: number; height: number; } | null; /** * Draw `src` into `ctx` at the origin, reduced by `2**n`, one halving at a * time. The destination must already be {@link halve}d to match. * * `ctx` must be at identity — the chain draws in destination pixels. */ export declare function drawHalved(ctx: CanvasRenderingContext2D, src: CanvasImageSource, sw: number, sh: number, n: number): void; //# sourceMappingURL=downscale.d.ts.map