meo-canvas
    Preparing search index...

    Class Canvas

    A painted canvas, and the ways to read it back.

    Constructed by Root; a caller never builds one. It holds the native surface and nothing else, so every method here is an encode of work already done.

    Index
    • Wraps a native surface.

      One argument, where there were three. The other two were a filesystem, injected so this class could be tested without a disk. They cannot survive the encode moving into the file: toFile no longer produces a buffer for anyone to write, so a caller supplying a writer would have been passing something nothing could call — a documented capability that silently did nothing.

      The seam did not go, it moved. A test substitutes a NativeCanvas, which is where encode was always mocked anyway, and a host without node:fs supplies one too. One injection point instead of two.

      Parameters

      Returns Canvas

    • get apng(): Promise<Uint8Array<ArrayBufferLike>>

      toBuffer('apng'). Every page as a frame, with PNG's colour and alpha.

      Returns Promise<Uint8Array<ArrayBufferLike>>

    • get avif(): Promise<Uint8Array<ArrayBufferLike>>

      toBuffer('avif'). Smaller again, and slower to encode.

      Returns Promise<Uint8Array<ArrayBufferLike>>

    • get bmp(): Promise<Uint8Array<ArrayBufferLike>>

      toBuffer('bmp'). Uncompressed, and rarely what is wanted.

      Returns Promise<Uint8Array<ArrayBufferLike>>

    • get engine(): string

      Which rasteriser drew the pages: 'gpu' or 'cpu'.

      The outcome rather than the request, and they disagree: a build with no GPU backend compiled, a driver that declines, and a float colorType all rasterise on the CPU whatever gpu says. v1 reports both for this reason, and without it a caller who asks for the GPU and gets the CPU has no way to find out — the same shape of invisibility that hid a missing build feature from this project for a session.

      Returns string

    • get gif(): Promise<Uint8Array<ArrayBufferLike>>

      toBuffer('gif'). Every page as a frame, at 256 colours.

      Returns Promise<Uint8Array<ArrayBufferLike>>

    • get gpu(): boolean

      Whether the GPU was asked for.

      Asking is not getting — compare Canvas.engine. This is what Root was told, and it is true when nothing was said, because that is the renderer's own default.

      Returns boolean

    • get ico(): Promise<Uint8Array<ArrayBufferLike>>

      toBuffer('ico'). The Windows icon container.

      Returns Promise<Uint8Array<ArrayBufferLike>>

    • get jpg(): Promise<Uint8Array<ArrayBufferLike>>

      toBuffer('jpg'). Lossy and opaque — no alpha channel.

      Returns Promise<Uint8Array<ArrayBufferLike>>

    • get pageCount(): number

      How many pages were painted.

      What a page means is the format's answer: a frame for GIF and APNG, a sheet for PDF and TIFF, one size of the same icon for ICO.

      Returns number

    • get pdf(): Promise<Uint8Array<ArrayBufferLike>>

      toBuffer('pdf'). Vector, and every page a page.

      Returns Promise<Uint8Array<ArrayBufferLike>>

    • get png(): Promise<Uint8Array<ArrayBufferLike>>

      toBuffer('png'). Lossless, and the format to reach for without a reason not to.

      Returns Promise<Uint8Array<ArrayBufferLike>>

    • get raw(): Promise<Uint8Array<ArrayBufferLike>>

      toBuffer('raw'). The pixels, unencoded.

      Returns Promise<Uint8Array<ArrayBufferLike>>

    • get released(): boolean

      Whether the surface is still there.

      Returns boolean

    • get scale(): number

      The device-pixel multiplier the pages were drawn at.

      Layout always solves at one, so this is resolution rather than anything about where things sit.

      Returns number

    • get svg(): Promise<Uint8Array<ArrayBufferLike>>

      toBuffer('svg'). Vector, so text stays text.

      Returns Promise<Uint8Array<ArrayBufferLike>>

    • get tiff(): Promise<Uint8Array<ArrayBufferLike>>

      toBuffer('tiff'). Lossless, and what a print pipeline usually asks for.

      Returns Promise<Uint8Array<ArrayBufferLike>>

    • get webp(): Promise<Uint8Array<ArrayBufferLike>>

      toBuffer('webp'). Smaller than PNG at the same quality, and takes every page as an animation.

      Returns Promise<Uint8Array<ArrayBufferLike>>

    • Frees the Skia surface now rather than at the next collection.

      Optional. The surface is freed when this canvas is collected either way; this only makes it sooner, which a server rendering thousands of images wants and a script does not need. Calling it twice is not an error, and every other method throws afterwards rather than reading freed memory.

      Returns void

    • Encodes the canvas on a worker thread and resolves with the bytes.

      This is where the pixels are allocated, because painting recorded a drawing rather than a bitmap. So this is what costs time in proportion to the canvas area — about 11 ms at 800×800, 65 ms at 2000×2000 and 256 ms at 4000×4000 on one machine — and this is what throws when the area is more than the host can allocate, however long ago the size was chosen.

      That time is not spent on the event loop. It used to be: this method returned a promise that was already settled, having blocked every other request in the process for the whole encode, so await bought a tick and nothing else. What crosses to the worker is the recorded pages, not the scene — the drawing is already shaped, so the worker consults no font and cannot substitute one.

      The remaining loop time is the half of an export that needs the canvas, which is small and does not grow with area the way the encode does.

      See Canvas.toBufferSync for why the type is Buffer.

      Parameters

      Returns Promise<Buffer<ArrayBufferLike>>

    • Encodes the canvas and returns the bytes.

      The same bytes Canvas.toBuffer resolves with, produced on the calling thread instead of a worker. A genuine choice rather than the same call twice: this one blocks the event loop for the whole encode, which is what a script wants and what a server does not.

      Why Buffer and not Uint8Array

      Because a Buffer is what already came back. The addon returns a Neon JsBuffer and always has; the declaration said Uint8Array, which was a false statement about the value. Buffer extends Uint8Array, so this narrows the type without changing a byte, and every caller that wanted either is satisfied.

      It is not a fix for sharp. sharp accepts a plain Uint8Array — its SharpInput names the type, and 0.34.5, 0.35.3 and 0.35.4 each read one back to png 410x140 when measured. Whatever a caller hit handing this to sharp, this was not it, and the type being honest is worth having on its own.

      Parameters

      Returns Buffer

    • The HTMLCanvasElement spelling of Canvas.toURLSync.

      Synchronous and taking a quality rather than an options object, because the DOM method it is named after is both. v1 has it for the same reason.

      Parameters

      • Optionalformat: Format
      • Optionalquality: number

      Returns string

    • Encodes the canvas on a worker and writes it to path.

      The bytes never come back through JavaScript. They used to: this encoded to a Buffer, resolved it here, and handed it to a write — so a three-hundred-frame animation had to exist whole in memory before any of it reached the disk. The file is now written where it is encoded, and a spanning format streams into it page by page.

      That is also why the filesystem injected into the constructor is not on this path any more. It cannot be: the point is that no buffer crosses back for anyone to write.

      Parameters

      Returns Promise<void>

    • Encodes the canvas and writes it to path, blocking.

      The same call on the calling thread. It asks the format question once, on this side, and everything after that is the one decision made in one place — see NativeCanvas.write.

      Parameters

      Returns void

    • Encodes the canvas on a worker and resolves with a data: URL.

      The base64 runs on the calling thread, which is where it has to: it is a string, and a string cannot cross to a worker without being copied twice. It is also the cheap end — a 4000×4000 PNG is tens of kilobytes by the time it is bytes, against the hundred milliseconds that made it.

      Parameters

      Returns Promise<string>

    • Encodes the canvas and returns a data: URL.

      Parameters

      Returns string