ComposeCanvas
KiteCanvas backed by a Compose Multiplatform DrawScope.
Three rendering paths:
Embedded outlines: when
hasOutlinesis true, each byte/CID becomes a ComposePathfilled at the right position.System-font fallback: when no outlines are available, decode to text and hand to Compose's
TextMeasurer.Transparency groups: open a
saveLayeron the underlying Canvas when the renderer requests one; laterrestorecomposites the layer back with the requested blend mode + alpha.
Clips and transparency groups use the lower-level Canvas.save, clipPath and saveLayer, so they span many DrawScope operations, and each clip is applied once however many paints it covers.
On the desktop JVM, iOS, macOS and Android, system-font text and host glyph outlines are shaped by the platform's own text engine, not by Compose's text stack, so they draw on any thread (#131, #487). In a browser they go through Compose's text and require the UI thread; a call on another thread throws IllegalStateException before accessing the host text stack. For background exports use KitePageRasterizer.rasterizeOffMain. A canvas that skips system text can probe on a worker, but that incomplete bitmap is not an export (#428). The canvas of a Vectorized page in KiteDocView draws inside its scene's own draw pass, so its host text takes the thread that scene draws on (#464).
Functions
Soft-mask compositing (ISO 32000-1 §11.6.5). We open a saveLayer for the content, render it, then over-paint the mask group with ComposeBlendMode.DstIn so the mask's alpha clips the content.
Transparency groups: open a Compose saveLayer on the active Canvas with a Paint that carries the requested alpha + blend mode. Subsequent draws accumulate into the offscreen layer; matching endTransparencyGroup calls restore, which composites the layer onto the parent.
The outline of text in the host face drawGlyphs draws a font without embedded outlines in, at 1000 units per em with y up (#85). Off the main thread it only records the run, as the system-font path does, so the page renders again on Main.
The raster step (#209, #308): its box is region under ctm, in the units of the draw scope, cut to the clip and rounded out to whole units. It works at magnification pixels a unit, so a step on a zoomed Vectorized page keeps the detail on screen, and past STEP_MAX_PIXELS at a lower resolution. Only a rasterizer's canvas, which knows the bitmap it draws into, reads a backdrop, and only outside every layer.