Canvas2dCanvas

KiteCanvas backed by a browser-side CanvasRenderingContext2D. Pure Kotlin/JS + DOM: no Compose for Web, no Skia/WASM bundle.

The right choice for in-browser PDF viewers that want minimal bundle size and to inherit whatever rendering acceleration the browser already provides for <canvas>.

Honest scope:

  • Path operations, gradients, blend modes (all 16) and clipping use the standard Canvas2D API. A transparency group with an alpha or a blend mode, and a soft mask, paint into an offscreen canvas that composites onto the page once.

  • Embedded image XObjects: a RAW image, which is what the shared decoders produce, paints synchronously. Every other kind paints a placeholder, as on every canvas (#184).

Constructors

Link copied to clipboard
constructor(ctx: CanvasRenderingContext2D)

Properties

Link copied to clipboard

Functions

Link copied to clipboard
open override fun applySoftMask(kind: SoftMask.Kind, maskBBox: KiteRectangle, maskCtm: KiteMatrix, render: () -> Unit, renderMask: (KiteCanvas) -> Unit)

open override fun applySoftMask(kind: SoftMask.Kind, maskBBox: KiteRectangle, maskCtm: KiteMatrix, transfer: KiteMaskTransfer?, render: () -> Unit, renderMask: (KiteCanvas) -> Unit)

ISO 32000-1, 11.6.5.2: the content and the mask group each paint into a layer of their own. The mask layer's alpha, or for a luminosity mask its luminosity over a black backdrop, gates the content layer, which then composites onto the page. The mask group's colours never reach the page (#161). The transfer table maps each mask value.

Link copied to clipboard
open override fun beginPage(widthPt: Double, heightPt: Double, deviceCtm: KiteMatrix)
Link copied to clipboard
open override fun beginTransparencyGroup(bbox: KiteRectangle, ctm: KiteMatrix, isolated: Boolean, knockout: Boolean, alpha: Double, blendMode: KiteBlendMode)

ISO 32000-1, 11.4.5: a group's constant alpha and blend mode apply once, when the group composites onto its backdrop. So a group that has them paints into a layer first (#77). An isolated group's layer starts transparent. A non-isolated group's layer starts as a copy of the backdrop, so a paint inside blends with the page, and at the end the layer mixes with the page by alpha. That is exact over an opaque backdrop. A non-isolated group with a blend mode of its own starts transparent, which is exact when no paint inside blends (#125).

Link copied to clipboard
open override fun drawGlyphs(glyphs: List<TextGlyph>, fontSize: Double, unitsPerEm: Int, hasOutlines: Boolean, fontSpec: FontSpec, textToDevice: KiteMatrix, color: RgbColor, alpha: Double, blendMode: KiteBlendMode)
Link copied to clipboard
open override fun drawImage(image: KiteImageData, ctm: KiteMatrix, alpha: Double)
open override fun drawImage(image: KiteImageData, ctm: KiteMatrix, alpha: Double, blendMode: KiteBlendMode)
Link copied to clipboard
open override fun endPage()
Link copied to clipboard
open override fun endTransparencyGroup()
Link copied to clipboard
open override fun fillPath(path: KitePath, ctm: KiteMatrix, color: RgbColor, evenOdd: Boolean, alpha: Double, blendMode: KiteBlendMode)
Link copied to clipboard
open override fun fillShading(shading: KiteShading, ctm: KiteMatrix, clipPath: KitePath?, alpha: Double, blendMode: KiteBlendMode)
Link copied to clipboard
open fun hostGlyphOutline(text: String, fontSpec: FontSpec): KitePath?
Link copied to clipboard
open override fun popClip()
Link copied to clipboard
open override fun pushClip(path: KitePath, ctm: KiteMatrix, evenOdd: Boolean)
Link copied to clipboard
open override fun rasterStep(region: KiteRectangle, ctm: KiteMatrix, step: KiteRasterStep): Boolean

The raster step (#209, #308): its box is region under ctm in device pixels, cut to the canvas that paints go to now. A render paints into an offscreen canvas of the box, as a group's layer does, and the backdrop comes from the canvas under the step, a layer or the page, through getImageData.

Link copied to clipboard
open override fun strokePath(path: KitePath, ctm: KiteMatrix, color: RgbColor, lineWidth: Double, alpha: Double, blendMode: KiteBlendMode, dashArray: List<Double>?, dashPhase: Double, lineCap: Int, lineJoin: Int, miterLimit: Double)