meo-skia-canvas
    Preparing search index...

    Interface CanvasOptions

    What a canvas is built with, beyond its size.

    The third argument to the Canvas constructor, and mixed into WindowOptions for the canvas a window creates for itself. Every field is fixed at construction rather than per draw: the colour space and pixel format chosen here are what the pages composite in, and an export converts out of them rather than changing them.

    The Rust crate spells this CanvasOptions with the same fields, so a drawing ported between the two surfaces reads the same on both.

    🧪 Not in the HTML Canvas standard.

    interface CanvasOptions {
        colorSpace?: ColorSpace;
        colorType?: ColorType;
        gpu?: boolean;
        textContrast?: number;
        textGamma?: number;
    }
    Index
    colorSpace?: ColorSpace

    The space the canvas composites in (defaults to "srgb").

    Fixed here rather than per export: colours are interpreted in it, and one outside its gamut is clipped as it is drawn. Exports and readbacks default to it and convert out of it when asked for another.

    colorType?: ColorType

    Pixel format exports and getImageData hand pixels back in (defaults to "rgba").

    On a canvas, a float format ("RGBAF16", "RGBAF32") also selects what the page composites in, so blending keeps the fractions eight bits round away: sixty layers at 0.6% alpha land on 0.30308 (RGBAF32) and 0.30298 (RGBAF16) against an arithmetic answer of 0.30308, where eight bits compound their rounding into 0.23922. It costs twice the memory for RGBAF16 and four times for RGBAF32. The time cost depends on what is drawn rather than on the pixel width: 120 translucent layers are faster in float (0.74x and 0.77x, since an eight-bit surface converts through its transfer function on every layer and a float one does not), while 120 opaque fills cost 1.29x in RGBAF16 and 7.58x in RGBAF32. Every other format composites at eight bits and converts on the way out -- an opaque or narrower one would lose more inside the page than it saves.

    On a toBuffer or getImageData call it means only the layout of the buffer you receive; the page keeps the format its canvas was built with.

    A float canvas renders on the raster backend, whatever gpu says, and canvas.engine reports which one took it. No GPU can currently deliver the precision: Skia's Metal and Vulkan backends implement no 32-bit float surface at all, and while both provide RGBAF16, a GPU quantises the paint colour to eight bits before compositing -- the same sixty layers land on 0.235 there, further from 0.303 than the eight-bit answer of 0.361. Asking for float and being handed eight bits would be the worse trade, so the canvas changes engine instead.

    This is probed at runtime rather than assumed, so a Skia that grows the support keeps such canvases on the GPU with no change here.

    gpu?: boolean

    Whether to rasterize on the GPU when one is available (defaults to true). Set false to force the CPU backend.

    Asking is not getting: Canvas.gpu reports the engine the canvas settled on, so it reads false on a build with no GPU support, on a machine whose driver declined, and on a float canvas, which no GPU can composite. Canvas.engine says which of those it was.

    textContrast?: number

    How much the rasterizer thickens small text, from 0 to 1 (defaults to 0).

    Glyph stems below a pixel wide antialias to something lighter than the same shape at a larger size, and this compensates. The default is no compensation.

    textGamma?: number

    The gamma the rasterizer corrects glyph coverage against (defaults to 1.4).

    Works with CanvasOptions.textContrast: coverage is a linear quantity and the display is not, so blending glyph edges without accounting for that renders light text on dark thinner than dark on light. The default is Skia's own tuned value.