Skip to content

fix: use signed integers for canvas APIs that accept negative coordinates#1227

Merged
Brooooooklyn merged 3 commits intomainfrom
fix/type-casting-negative-values
Mar 16, 2026
Merged

fix: use signed integers for canvas APIs that accept negative coordinates#1227
Brooooooklyn merged 3 commits intomainfrom
fix/type-casting-negative-values

Conversation

@Brooooooklyn
Copy link
Owner

@Brooooooklyn Brooooooklyn commented Mar 15, 2026

putImageData, getImageData, and createImageData used u32 for coordinate/dimension
parameters, silently corrupting negative values from JavaScript. The HTML Canvas
spec defines these as signed (long) or using absolute values. Changed to i32 across
the call chain (ctx.rs, sk.rs, page_recorder.rs) so negative values propagate
correctly to the underlying Skia FFI which already accepts signed ints.

Co-Authored-By: Claude Opus 4.6 (1M context) noreply@anthropic.com


Note

Medium Risk
Changes the JS-facing getImageData/putImageData/createImageData argument types and pixel IO call chain to accept negative values, which can affect rendering output and bounds handling across deferred and direct rendering paths.

Overview
Fixes Canvas ImageData APIs to follow the HTML spec for signed coordinates and negative dimensions instead of silently corrupting negatives via u32 casts.

This updates the Rust/N-API layer and Skia plumbing to use signed i32 for pixel read/write origins (get_image_data/read_pixels/write_pixels and PageRecorder::get_pixels), applies spec behavior for negative getImageData width/height (flip origin + abs size), and makes createImageData treat negative sizes as absolute.

Adds regression tests covering putImageData with negative dx/dy, getImageData with negative x/y and negative width/height, and createImageData with negative dimensions.

Written by Cursor Bugbot for commit 7dd91e9. This will update automatically on new commits. Configure here.

…ates

putImageData, getImageData, and createImageData used u32 for coordinate/dimension
parameters, silently corrupting negative values from JavaScript. The HTML Canvas
spec defines these as signed (long) or using absolute values. Changed to i32 across
the call chain (ctx.rs, sk.rs, page_recorder.rs) so negative values propagate
correctly to the underlying Skia FFI which already accepts signed ints.

- Close #1226

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Copy link
Owner Author

This stack of pull requests is managed by Graphite. Learn more about stacking.

Copy link

@cursor cursor bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Fix All in Cursor

Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Brooooooklyn and others added 2 commits March 16, 2026 10:04
The as u32 cast on negative i32 wraps via two's complement (e.g. -1i32 as u32
= 4294967295), unlike unsigned_abs() which correctly produces the absolute value.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Per the spec, getImageData(sx, sy, sw, sh) with negative sw/sh should flip the
origin (sx += sw, sy += sh) and use absolute values. Previously, negative f32
values were cast as u32 (saturating to 0), causing "Read pixels from canvas
failed" errors.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@Brooooooklyn Brooooooklyn merged commit fa7c7c1 into main Mar 16, 2026
40 checks passed
@Brooooooklyn Brooooooklyn deleted the fix/type-casting-negative-values branch March 16, 2026 02:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Regression: putImageData not drawing image if dx < 0 or dy < 0 since 0.1.89

1 participant