mirror of
https://github.com/lightpanda-io/browser.git
synced 2026-03-22 04:34:44 +00:00
Merge pull request #1564 from lightpanda-io/nikneym/create-image-data
Add `createImageData` and `putImageData` to `CanvasRenderingContext2D`
This commit is contained in:
@@ -33,3 +33,58 @@
|
||||
testing.expectEqual(ctx.fillStyle, "rgba(255, 0, 0, 0.06)");
|
||||
}
|
||||
</script>
|
||||
|
||||
<script id="CanvasRenderingContext2D#createImageData(width, height)">
|
||||
{
|
||||
const element = document.createElement("canvas");
|
||||
const ctx = element.getContext("2d");
|
||||
|
||||
const imageData = ctx.createImageData(100, 200);
|
||||
testing.expectEqual(true, imageData instanceof ImageData);
|
||||
testing.expectEqual(imageData.width, 100);
|
||||
testing.expectEqual(imageData.height, 200);
|
||||
testing.expectEqual(imageData.data.length, 100 * 200 * 4);
|
||||
testing.expectEqual(true, imageData.data instanceof Uint8ClampedArray);
|
||||
|
||||
// All pixels should be initialized to 0.
|
||||
testing.expectEqual(imageData.data[0], 0);
|
||||
testing.expectEqual(imageData.data[1], 0);
|
||||
testing.expectEqual(imageData.data[2], 0);
|
||||
testing.expectEqual(imageData.data[3], 0);
|
||||
}
|
||||
</script>
|
||||
|
||||
<script id="CanvasRenderingContext2D#createImageData(imageData)">
|
||||
{
|
||||
const element = document.createElement("canvas");
|
||||
const ctx = element.getContext("2d");
|
||||
|
||||
const source = ctx.createImageData(50, 75);
|
||||
const imageData = ctx.createImageData(source);
|
||||
testing.expectEqual(true, imageData instanceof ImageData);
|
||||
testing.expectEqual(imageData.width, 50);
|
||||
testing.expectEqual(imageData.height, 75);
|
||||
testing.expectEqual(imageData.data.length, 50 * 75 * 4);
|
||||
}
|
||||
</script>
|
||||
|
||||
<script id="CanvasRenderingContext2D#putImageData">
|
||||
{
|
||||
const element = document.createElement("canvas");
|
||||
const ctx = element.getContext("2d");
|
||||
|
||||
const imageData = ctx.createImageData(10, 10);
|
||||
testing.expectEqual(true, imageData instanceof ImageData);
|
||||
// Modify some pixel data.
|
||||
imageData.data[0] = 255;
|
||||
imageData.data[1] = 0;
|
||||
imageData.data[2] = 0;
|
||||
imageData.data[3] = 255;
|
||||
|
||||
// putImageData should not throw.
|
||||
ctx.putImageData(imageData, 0, 0);
|
||||
ctx.putImageData(imageData, 10, 20);
|
||||
// With dirty rect parameters.
|
||||
ctx.putImageData(imageData, 0, 0, 0, 0, 5, 5);
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -59,10 +59,6 @@
|
||||
}
|
||||
</script>
|
||||
|
||||
<script id=constructor-invalid-colorspace>
|
||||
testing.expectError("TypeError", () => {
|
||||
new ImageData(5, 5, { colorSpace: "display-p3" });
|
||||
});
|
||||
</script>
|
||||
|
||||
<script id=single-pixel>
|
||||
@@ -73,3 +69,7 @@
|
||||
testing.expectEqual(1, img.height);
|
||||
}
|
||||
</script>
|
||||
|
||||
<script id=too-large>
|
||||
testing.expectError("IndexSizeError", () => new ImageData(2_147_483_648, 2_147_483_648));
|
||||
</script>
|
||||
|
||||
@@ -58,7 +58,10 @@ pub fn constructor(
|
||||
maybe_settings: ?ConstructorSettings,
|
||||
page: *Page,
|
||||
) !*ImageData {
|
||||
if (width == 0 or height == 0) {
|
||||
// Though arguments are unsigned long, these are capped to max. i32 on Chrome.
|
||||
// https://github.com/chromium/chromium/blob/main/third_party/blink/renderer/core/html/canvas/image_data.cc#L61
|
||||
const max_i32 = std.math.maxInt(i32);
|
||||
if (width == 0 or width > max_i32 or height == 0 or height > max_i32) {
|
||||
return error.IndexSizeError;
|
||||
}
|
||||
|
||||
@@ -70,7 +73,11 @@ pub fn constructor(
|
||||
return error.TypeError;
|
||||
}
|
||||
|
||||
const size = width * height * 4;
|
||||
var size, var overflown = @mulWithOverflow(width, height);
|
||||
if (overflown == 1) return error.IndexSizeError;
|
||||
size, overflown = @mulWithOverflow(size, 4);
|
||||
if (overflown == 1) return error.IndexSizeError;
|
||||
|
||||
return page._factory.create(ImageData{
|
||||
._width = width,
|
||||
._height = height,
|
||||
|
||||
@@ -23,6 +23,8 @@ const js = @import("../../js/js.zig");
|
||||
const color = @import("../../color.zig");
|
||||
const Page = @import("../../Page.zig");
|
||||
|
||||
const ImageData = @import("../ImageData.zig");
|
||||
|
||||
/// This class doesn't implement a `constructor`.
|
||||
/// It can be obtained with a call to `HTMLCanvasElement#getContext`.
|
||||
/// https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D
|
||||
@@ -85,6 +87,33 @@ pub fn getTextBaseline(_: *const CanvasRenderingContext2D) []const u8 {
|
||||
return "alphabetic";
|
||||
}
|
||||
|
||||
const WidthOrImageData = union(enum) {
|
||||
width: u32,
|
||||
image_data: *ImageData,
|
||||
};
|
||||
|
||||
pub fn createImageData(
|
||||
_: *const CanvasRenderingContext2D,
|
||||
width_or_image_data: WidthOrImageData,
|
||||
/// If `ImageData` variant preferred, this is null.
|
||||
maybe_height: ?u32,
|
||||
/// Can be used if width and height provided.
|
||||
maybe_settings: ?ImageData.ConstructorSettings,
|
||||
page: *Page,
|
||||
) !*ImageData {
|
||||
switch (width_or_image_data) {
|
||||
.width => |width| {
|
||||
const height = maybe_height orelse return error.TypeError;
|
||||
return ImageData.constructor(width, height, maybe_settings, page);
|
||||
},
|
||||
.image_data => |image_data| {
|
||||
return ImageData.constructor(image_data._width, image_data._height, null, page);
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
pub fn putImageData(_: *const CanvasRenderingContext2D, _: *ImageData, _: f64, _: f64, _: ?f64, _: ?f64, _: ?f64, _: ?f64) void {}
|
||||
|
||||
pub fn save(_: *CanvasRenderingContext2D) void {}
|
||||
pub fn restore(_: *CanvasRenderingContext2D) void {}
|
||||
pub fn scale(_: *CanvasRenderingContext2D, _: f64, _: f64) void {}
|
||||
@@ -131,6 +160,9 @@ pub const JsApi = struct {
|
||||
pub var class_id: bridge.ClassId = undefined;
|
||||
};
|
||||
|
||||
pub const createImageData = bridge.function(CanvasRenderingContext2D.createImageData, .{ .dom_exception = true });
|
||||
pub const putImageData = bridge.function(CanvasRenderingContext2D.putImageData, .{});
|
||||
|
||||
pub const save = bridge.function(CanvasRenderingContext2D.save, .{});
|
||||
pub const restore = bridge.function(CanvasRenderingContext2D.restore, .{});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user