Phase 18: Canvas 2D API — Issue 9/10#
Implement pixel-level read/write access to canvas image data.
Dependencies#
- Canvas element infrastructure (issue 1)
Requirements#
ImageData interface:
new ImageData(width, height)— create with transparent black pixelsnew ImageData(data, width, height?)— create from existing Uint8ClampedArray- Properties:
width,height,data(Uint8ClampedArray view of RGBA8 pixels) - Throw if dimensions are zero or data length doesn't match width × height × 4
Uint8ClampedArray in JS engine:
- Typed array that clamps values to [0, 255] on assignment
- Supports indexing, length property, iteration
- Backed by a contiguous byte buffer
- This may require extending the JS engine's typed array support
Context methods:
createImageData(width, height)— return new ImageData with transparent blackcreateImageData(imagedata)— return new ImageData with same dimensions (but blank)getImageData(sx, sy, sw, sh)— read pixels from canvas into new ImageDataputImageData(imagedata, dx, dy)— write pixels from ImageData to canvasputImageData(imagedata, dx, dy, dirtyX, dirtyY, dirtyW, dirtyH)— write only the dirty sub-rect
Behavior:
- getImageData reads pre-multiplied alpha pixels and un-premultiplies them
- putImageData writes directly without compositing (bypasses globalAlpha, CTM, compositeOp)
- Source/dest coordinates can be negative (clips to canvas bounds)
- Throw IndexSizeError for zero or negative width/height
Acceptance criteria#
- getImageData reads correct pixel values from a canvas with drawn content
- putImageData writes raw pixels that are visible in the rendered canvas
- createImageData creates correctly sized blank ImageData
- Uint8ClampedArray clamps values:
data[0] = 300results in 255,data[0] = -5results in 0 - Dirty rectangle optimization in putImageData only writes the specified sub-region
- Unit tests for pixel read/write round-trip, clamping, and dirty rect clipping