mirror of
https://github.com/lightpanda-io/browser.git
synced 2026-03-22 04:34:44 +00:00
Merge pull request #1620 from lightpanda-io/offscreen_canvas
Add dummy implementation of OffscreenCanvas
This commit is contained in:
@@ -866,6 +866,8 @@ pub const JsApis = flattenTypes(&.{
|
|||||||
@import("../webapi/navigation/NavigationActivation.zig"),
|
@import("../webapi/navigation/NavigationActivation.zig"),
|
||||||
@import("../webapi/canvas/CanvasRenderingContext2D.zig"),
|
@import("../webapi/canvas/CanvasRenderingContext2D.zig"),
|
||||||
@import("../webapi/canvas/WebGLRenderingContext.zig"),
|
@import("../webapi/canvas/WebGLRenderingContext.zig"),
|
||||||
|
@import("../webapi/canvas/OffscreenCanvas.zig"),
|
||||||
|
@import("../webapi/canvas/OffscreenCanvasRenderingContext2D.zig"),
|
||||||
@import("../webapi/SubtleCrypto.zig"),
|
@import("../webapi/SubtleCrypto.zig"),
|
||||||
@import("../webapi/Selection.zig"),
|
@import("../webapi/Selection.zig"),
|
||||||
@import("../webapi/ImageData.zig"),
|
@import("../webapi/ImageData.zig"),
|
||||||
|
|||||||
64
src/browser/tests/canvas/offscreen_canvas.html
Normal file
64
src/browser/tests/canvas/offscreen_canvas.html
Normal file
@@ -0,0 +1,64 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<script src="../testing.js"></script>
|
||||||
|
|
||||||
|
<script id=OffscreenCanvas>
|
||||||
|
{
|
||||||
|
const canvas = new OffscreenCanvas(256, 256);
|
||||||
|
testing.expectEqual(true, canvas instanceof OffscreenCanvas);
|
||||||
|
testing.expectEqual(canvas.width, 256);
|
||||||
|
testing.expectEqual(canvas.height, 256);
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<script id=OffscreenCanvas#width>
|
||||||
|
{
|
||||||
|
const canvas = new OffscreenCanvas(100, 200);
|
||||||
|
testing.expectEqual(canvas.width, 100);
|
||||||
|
canvas.width = 300;
|
||||||
|
testing.expectEqual(canvas.width, 300);
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<script id=OffscreenCanvas#height>
|
||||||
|
{
|
||||||
|
const canvas = new OffscreenCanvas(100, 200);
|
||||||
|
testing.expectEqual(canvas.height, 200);
|
||||||
|
canvas.height = 400;
|
||||||
|
testing.expectEqual(canvas.height, 400);
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<script id=OffscreenCanvas#getContext>
|
||||||
|
{
|
||||||
|
const canvas = new OffscreenCanvas(64, 64);
|
||||||
|
const ctx = canvas.getContext("2d");
|
||||||
|
testing.expectEqual(true, ctx instanceof OffscreenCanvasRenderingContext2D);
|
||||||
|
// We can't really test rendering but let's try to call it at least.
|
||||||
|
ctx.fillRect(0, 0, 10, 10);
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<script id=OffscreenCanvas#convertToBlob>
|
||||||
|
{
|
||||||
|
const canvas = new OffscreenCanvas(64, 64);
|
||||||
|
const promise = canvas.convertToBlob();
|
||||||
|
testing.expectEqual(true, promise instanceof Promise);
|
||||||
|
// The promise should resolve to a Blob (even if empty)
|
||||||
|
promise.then(blob => {
|
||||||
|
testing.expectEqual(true, blob instanceof Blob);
|
||||||
|
testing.expectEqual(blob.size, 0); // Empty since no rendering
|
||||||
|
});
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<script id=HTMLCanvasElement#transferControlToOffscreen>
|
||||||
|
{
|
||||||
|
const htmlCanvas = document.createElement("canvas");
|
||||||
|
htmlCanvas.width = 128;
|
||||||
|
htmlCanvas.height = 96;
|
||||||
|
const offscreen = htmlCanvas.transferControlToOffscreen();
|
||||||
|
testing.expectEqual(true, offscreen instanceof OffscreenCanvas);
|
||||||
|
testing.expectEqual(offscreen.width, 128);
|
||||||
|
testing.expectEqual(offscreen.height, 96);
|
||||||
|
}
|
||||||
|
</script>
|
||||||
105
src/browser/webapi/canvas/OffscreenCanvas.zig
Normal file
105
src/browser/webapi/canvas/OffscreenCanvas.zig
Normal file
@@ -0,0 +1,105 @@
|
|||||||
|
// Copyright (C) 2023-2026 Lightpanda (Selecy SAS)
|
||||||
|
//
|
||||||
|
// Francis Bouvier <francis@lightpanda.io>
|
||||||
|
// Pierre Tachoire <pierre@lightpanda.io>
|
||||||
|
//
|
||||||
|
// This program is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU Affero General Public License as
|
||||||
|
// published by the Free Software Foundation, either version 3 of the
|
||||||
|
// License, or (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU Affero General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU Affero General Public License
|
||||||
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
const std = @import("std");
|
||||||
|
const js = @import("../../js/js.zig");
|
||||||
|
const Page = @import("../../Page.zig");
|
||||||
|
|
||||||
|
const Blob = @import("../Blob.zig");
|
||||||
|
const OffscreenCanvasRenderingContext2D = @import("OffscreenCanvasRenderingContext2D.zig");
|
||||||
|
|
||||||
|
/// https://developer.mozilla.org/en-US/docs/Web/API/OffscreenCanvas
|
||||||
|
const OffscreenCanvas = @This();
|
||||||
|
|
||||||
|
pub const _prototype_root = true;
|
||||||
|
|
||||||
|
_width: u32,
|
||||||
|
_height: u32,
|
||||||
|
|
||||||
|
/// Since there's no base class rendering contextes inherit from,
|
||||||
|
/// we're using tagged union.
|
||||||
|
const DrawingContext = union(enum) {
|
||||||
|
@"2d": *OffscreenCanvasRenderingContext2D,
|
||||||
|
};
|
||||||
|
|
||||||
|
pub fn constructor(width: u32, height: u32, page: *Page) !*OffscreenCanvas {
|
||||||
|
return page._factory.create(OffscreenCanvas{
|
||||||
|
._width = width,
|
||||||
|
._height = height,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn getWidth(self: *const OffscreenCanvas) u32 {
|
||||||
|
return self._width;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn setWidth(self: *OffscreenCanvas, value: u32) void {
|
||||||
|
self._width = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn getHeight(self: *const OffscreenCanvas) u32 {
|
||||||
|
return self._height;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn setHeight(self: *OffscreenCanvas, value: u32) void {
|
||||||
|
self._height = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn getContext(_: *OffscreenCanvas, context_type: []const u8, page: *Page) !?DrawingContext {
|
||||||
|
if (std.mem.eql(u8, context_type, "2d")) {
|
||||||
|
const ctx = try page._factory.create(OffscreenCanvasRenderingContext2D{});
|
||||||
|
return .{ .@"2d" = ctx };
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns a Promise that resolves to a Blob containing the image.
|
||||||
|
/// Since we have no actual rendering, this returns an empty blob.
|
||||||
|
pub fn convertToBlob(_: *OffscreenCanvas, page: *Page) !js.Promise {
|
||||||
|
const blob = try Blob.init(null, null, page);
|
||||||
|
return page.js.local.?.resolvePromise(blob);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns an ImageBitmap with the rendered content (stub).
|
||||||
|
pub fn transferToImageBitmap(_: *OffscreenCanvas) ?void {
|
||||||
|
// ImageBitmap not implemented yet, return null
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub const JsApi = struct {
|
||||||
|
pub const bridge = js.Bridge(OffscreenCanvas);
|
||||||
|
|
||||||
|
pub const Meta = struct {
|
||||||
|
pub const name = "OffscreenCanvas";
|
||||||
|
pub const prototype_chain = bridge.prototypeChain();
|
||||||
|
pub var class_id: bridge.ClassId = undefined;
|
||||||
|
};
|
||||||
|
|
||||||
|
pub const constructor = bridge.constructor(OffscreenCanvas.constructor, .{});
|
||||||
|
pub const width = bridge.accessor(OffscreenCanvas.getWidth, OffscreenCanvas.setWidth, .{});
|
||||||
|
pub const height = bridge.accessor(OffscreenCanvas.getHeight, OffscreenCanvas.setHeight, .{});
|
||||||
|
pub const getContext = bridge.function(OffscreenCanvas.getContext, .{});
|
||||||
|
pub const convertToBlob = bridge.function(OffscreenCanvas.convertToBlob, .{});
|
||||||
|
pub const transferToImageBitmap = bridge.function(OffscreenCanvas.transferToImageBitmap, .{});
|
||||||
|
};
|
||||||
|
|
||||||
|
const testing = @import("../../../testing.zig");
|
||||||
|
test "WebApi: OffscreenCanvas" {
|
||||||
|
try testing.htmlRunner("canvas/offscreen_canvas.html", .{});
|
||||||
|
}
|
||||||
209
src/browser/webapi/canvas/OffscreenCanvasRenderingContext2D.zig
Normal file
209
src/browser/webapi/canvas/OffscreenCanvasRenderingContext2D.zig
Normal file
@@ -0,0 +1,209 @@
|
|||||||
|
// Copyright (C) 2023-2025 Lightpanda (Selecy SAS)
|
||||||
|
//
|
||||||
|
// Francis Bouvier <francis@lightpanda.io>
|
||||||
|
// Pierre Tachoire <pierre@lightpanda.io>
|
||||||
|
//
|
||||||
|
// This program is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU Affero General Public License as
|
||||||
|
// published by the Free Software Foundation, either version 3 of the
|
||||||
|
// License, or (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU Affero General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU Affero General Public License
|
||||||
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
const std = @import("std");
|
||||||
|
|
||||||
|
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 `OffscreenCanvas#getContext`.
|
||||||
|
/// https://developer.mozilla.org/en-US/docs/Web/API/OffscreenCanvasRenderingContext2D
|
||||||
|
const OffscreenCanvasRenderingContext2D = @This();
|
||||||
|
/// Fill color.
|
||||||
|
/// TODO: Add support for `CanvasGradient` and `CanvasPattern`.
|
||||||
|
_fill_style: color.RGBA = color.RGBA.Named.black,
|
||||||
|
|
||||||
|
pub fn getFillStyle(self: *const OffscreenCanvasRenderingContext2D, page: *Page) ![]const u8 {
|
||||||
|
var w = std.Io.Writer.Allocating.init(page.call_arena);
|
||||||
|
try self._fill_style.format(&w.writer);
|
||||||
|
return w.written();
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn setFillStyle(
|
||||||
|
self: *OffscreenCanvasRenderingContext2D,
|
||||||
|
value: []const u8,
|
||||||
|
) !void {
|
||||||
|
// Prefer the same fill_style if fails.
|
||||||
|
self._fill_style = color.RGBA.parse(value) catch self._fill_style;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn getGlobalAlpha(_: *const OffscreenCanvasRenderingContext2D) f64 {
|
||||||
|
return 1.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn getGlobalCompositeOperation(_: *const OffscreenCanvasRenderingContext2D) []const u8 {
|
||||||
|
return "source-over";
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn getStrokeStyle(_: *const OffscreenCanvasRenderingContext2D) []const u8 {
|
||||||
|
return "#000000";
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn getLineWidth(_: *const OffscreenCanvasRenderingContext2D) f64 {
|
||||||
|
return 1.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn getLineCap(_: *const OffscreenCanvasRenderingContext2D) []const u8 {
|
||||||
|
return "butt";
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn getLineJoin(_: *const OffscreenCanvasRenderingContext2D) []const u8 {
|
||||||
|
return "miter";
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn getMiterLimit(_: *const OffscreenCanvasRenderingContext2D) f64 {
|
||||||
|
return 10.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn getFont(_: *const OffscreenCanvasRenderingContext2D) []const u8 {
|
||||||
|
return "10px sans-serif";
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn getTextAlign(_: *const OffscreenCanvasRenderingContext2D) []const u8 {
|
||||||
|
return "start";
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn getTextBaseline(_: *const OffscreenCanvasRenderingContext2D) []const u8 {
|
||||||
|
return "alphabetic";
|
||||||
|
}
|
||||||
|
|
||||||
|
const WidthOrImageData = union(enum) {
|
||||||
|
width: u32,
|
||||||
|
image_data: *ImageData,
|
||||||
|
};
|
||||||
|
|
||||||
|
pub fn createImageData(
|
||||||
|
_: *const OffscreenCanvasRenderingContext2D,
|
||||||
|
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 OffscreenCanvasRenderingContext2D, _: *ImageData, _: f64, _: f64, _: ?f64, _: ?f64, _: ?f64, _: ?f64) void {}
|
||||||
|
|
||||||
|
pub fn save(_: *OffscreenCanvasRenderingContext2D) void {}
|
||||||
|
pub fn restore(_: *OffscreenCanvasRenderingContext2D) void {}
|
||||||
|
pub fn scale(_: *OffscreenCanvasRenderingContext2D, _: f64, _: f64) void {}
|
||||||
|
pub fn rotate(_: *OffscreenCanvasRenderingContext2D, _: f64) void {}
|
||||||
|
pub fn translate(_: *OffscreenCanvasRenderingContext2D, _: f64, _: f64) void {}
|
||||||
|
pub fn transform(_: *OffscreenCanvasRenderingContext2D, _: f64, _: f64, _: f64, _: f64, _: f64, _: f64) void {}
|
||||||
|
pub fn setTransform(_: *OffscreenCanvasRenderingContext2D, _: f64, _: f64, _: f64, _: f64, _: f64, _: f64) void {}
|
||||||
|
pub fn resetTransform(_: *OffscreenCanvasRenderingContext2D) void {}
|
||||||
|
pub fn setGlobalAlpha(_: *OffscreenCanvasRenderingContext2D, _: f64) void {}
|
||||||
|
pub fn setGlobalCompositeOperation(_: *OffscreenCanvasRenderingContext2D, _: []const u8) void {}
|
||||||
|
pub fn setStrokeStyle(_: *OffscreenCanvasRenderingContext2D, _: []const u8) void {}
|
||||||
|
pub fn setLineWidth(_: *OffscreenCanvasRenderingContext2D, _: f64) void {}
|
||||||
|
pub fn setLineCap(_: *OffscreenCanvasRenderingContext2D, _: []const u8) void {}
|
||||||
|
pub fn setLineJoin(_: *OffscreenCanvasRenderingContext2D, _: []const u8) void {}
|
||||||
|
pub fn setMiterLimit(_: *OffscreenCanvasRenderingContext2D, _: f64) void {}
|
||||||
|
pub fn clearRect(_: *OffscreenCanvasRenderingContext2D, _: f64, _: f64, _: f64, _: f64) void {}
|
||||||
|
pub fn fillRect(_: *OffscreenCanvasRenderingContext2D, _: f64, _: f64, _: f64, _: f64) void {}
|
||||||
|
pub fn strokeRect(_: *OffscreenCanvasRenderingContext2D, _: f64, _: f64, _: f64, _: f64) void {}
|
||||||
|
pub fn beginPath(_: *OffscreenCanvasRenderingContext2D) void {}
|
||||||
|
pub fn closePath(_: *OffscreenCanvasRenderingContext2D) void {}
|
||||||
|
pub fn moveTo(_: *OffscreenCanvasRenderingContext2D, _: f64, _: f64) void {}
|
||||||
|
pub fn lineTo(_: *OffscreenCanvasRenderingContext2D, _: f64, _: f64) void {}
|
||||||
|
pub fn quadraticCurveTo(_: *OffscreenCanvasRenderingContext2D, _: f64, _: f64, _: f64, _: f64) void {}
|
||||||
|
pub fn bezierCurveTo(_: *OffscreenCanvasRenderingContext2D, _: f64, _: f64, _: f64, _: f64, _: f64, _: f64) void {}
|
||||||
|
pub fn arc(_: *OffscreenCanvasRenderingContext2D, _: f64, _: f64, _: f64, _: f64, _: f64, _: ?bool) void {}
|
||||||
|
pub fn arcTo(_: *OffscreenCanvasRenderingContext2D, _: f64, _: f64, _: f64, _: f64, _: f64) void {}
|
||||||
|
pub fn rect(_: *OffscreenCanvasRenderingContext2D, _: f64, _: f64, _: f64, _: f64) void {}
|
||||||
|
pub fn fill(_: *OffscreenCanvasRenderingContext2D) void {}
|
||||||
|
pub fn stroke(_: *OffscreenCanvasRenderingContext2D) void {}
|
||||||
|
pub fn clip(_: *OffscreenCanvasRenderingContext2D) void {}
|
||||||
|
pub fn setFont(_: *OffscreenCanvasRenderingContext2D, _: []const u8) void {}
|
||||||
|
pub fn setTextAlign(_: *OffscreenCanvasRenderingContext2D, _: []const u8) void {}
|
||||||
|
pub fn setTextBaseline(_: *OffscreenCanvasRenderingContext2D, _: []const u8) void {}
|
||||||
|
pub fn fillText(_: *OffscreenCanvasRenderingContext2D, _: []const u8, _: f64, _: f64, _: ?f64) void {}
|
||||||
|
pub fn strokeText(_: *OffscreenCanvasRenderingContext2D, _: []const u8, _: f64, _: f64, _: ?f64) void {}
|
||||||
|
|
||||||
|
pub const JsApi = struct {
|
||||||
|
pub const bridge = js.Bridge(OffscreenCanvasRenderingContext2D);
|
||||||
|
|
||||||
|
pub const Meta = struct {
|
||||||
|
pub const name = "OffscreenCanvasRenderingContext2D";
|
||||||
|
|
||||||
|
pub const prototype_chain = bridge.prototypeChain();
|
||||||
|
pub var class_id: bridge.ClassId = undefined;
|
||||||
|
};
|
||||||
|
|
||||||
|
pub const createImageData = bridge.function(OffscreenCanvasRenderingContext2D.createImageData, .{ .dom_exception = true });
|
||||||
|
pub const putImageData = bridge.function(OffscreenCanvasRenderingContext2D.putImageData, .{});
|
||||||
|
|
||||||
|
pub const save = bridge.function(OffscreenCanvasRenderingContext2D.save, .{});
|
||||||
|
pub const restore = bridge.function(OffscreenCanvasRenderingContext2D.restore, .{});
|
||||||
|
|
||||||
|
pub const scale = bridge.function(OffscreenCanvasRenderingContext2D.scale, .{});
|
||||||
|
pub const rotate = bridge.function(OffscreenCanvasRenderingContext2D.rotate, .{});
|
||||||
|
pub const translate = bridge.function(OffscreenCanvasRenderingContext2D.translate, .{});
|
||||||
|
pub const transform = bridge.function(OffscreenCanvasRenderingContext2D.transform, .{});
|
||||||
|
pub const setTransform = bridge.function(OffscreenCanvasRenderingContext2D.setTransform, .{});
|
||||||
|
pub const resetTransform = bridge.function(OffscreenCanvasRenderingContext2D.resetTransform, .{});
|
||||||
|
|
||||||
|
pub const globalAlpha = bridge.accessor(OffscreenCanvasRenderingContext2D.getGlobalAlpha, OffscreenCanvasRenderingContext2D.setGlobalAlpha, .{});
|
||||||
|
pub const globalCompositeOperation = bridge.accessor(OffscreenCanvasRenderingContext2D.getGlobalCompositeOperation, OffscreenCanvasRenderingContext2D.setGlobalCompositeOperation, .{});
|
||||||
|
|
||||||
|
pub const fillStyle = bridge.accessor(OffscreenCanvasRenderingContext2D.getFillStyle, OffscreenCanvasRenderingContext2D.setFillStyle, .{});
|
||||||
|
pub const strokeStyle = bridge.accessor(OffscreenCanvasRenderingContext2D.getStrokeStyle, OffscreenCanvasRenderingContext2D.setStrokeStyle, .{});
|
||||||
|
|
||||||
|
pub const lineWidth = bridge.accessor(OffscreenCanvasRenderingContext2D.getLineWidth, OffscreenCanvasRenderingContext2D.setLineWidth, .{});
|
||||||
|
pub const lineCap = bridge.accessor(OffscreenCanvasRenderingContext2D.getLineCap, OffscreenCanvasRenderingContext2D.setLineCap, .{});
|
||||||
|
pub const lineJoin = bridge.accessor(OffscreenCanvasRenderingContext2D.getLineJoin, OffscreenCanvasRenderingContext2D.setLineJoin, .{});
|
||||||
|
pub const miterLimit = bridge.accessor(OffscreenCanvasRenderingContext2D.getMiterLimit, OffscreenCanvasRenderingContext2D.setMiterLimit, .{});
|
||||||
|
|
||||||
|
pub const clearRect = bridge.function(OffscreenCanvasRenderingContext2D.clearRect, .{});
|
||||||
|
pub const fillRect = bridge.function(OffscreenCanvasRenderingContext2D.fillRect, .{});
|
||||||
|
pub const strokeRect = bridge.function(OffscreenCanvasRenderingContext2D.strokeRect, .{});
|
||||||
|
|
||||||
|
pub const beginPath = bridge.function(OffscreenCanvasRenderingContext2D.beginPath, .{});
|
||||||
|
pub const closePath = bridge.function(OffscreenCanvasRenderingContext2D.closePath, .{});
|
||||||
|
pub const moveTo = bridge.function(OffscreenCanvasRenderingContext2D.moveTo, .{});
|
||||||
|
pub const lineTo = bridge.function(OffscreenCanvasRenderingContext2D.lineTo, .{});
|
||||||
|
pub const quadraticCurveTo = bridge.function(OffscreenCanvasRenderingContext2D.quadraticCurveTo, .{});
|
||||||
|
pub const bezierCurveTo = bridge.function(OffscreenCanvasRenderingContext2D.bezierCurveTo, .{});
|
||||||
|
pub const arc = bridge.function(OffscreenCanvasRenderingContext2D.arc, .{});
|
||||||
|
pub const arcTo = bridge.function(OffscreenCanvasRenderingContext2D.arcTo, .{});
|
||||||
|
pub const rect = bridge.function(OffscreenCanvasRenderingContext2D.rect, .{});
|
||||||
|
|
||||||
|
pub const fill = bridge.function(OffscreenCanvasRenderingContext2D.fill, .{});
|
||||||
|
pub const stroke = bridge.function(OffscreenCanvasRenderingContext2D.stroke, .{});
|
||||||
|
pub const clip = bridge.function(OffscreenCanvasRenderingContext2D.clip, .{});
|
||||||
|
|
||||||
|
pub const font = bridge.accessor(OffscreenCanvasRenderingContext2D.getFont, OffscreenCanvasRenderingContext2D.setFont, .{});
|
||||||
|
pub const textAlign = bridge.accessor(OffscreenCanvasRenderingContext2D.getTextAlign, OffscreenCanvasRenderingContext2D.setTextAlign, .{});
|
||||||
|
pub const textBaseline = bridge.accessor(OffscreenCanvasRenderingContext2D.getTextBaseline, OffscreenCanvasRenderingContext2D.setTextBaseline, .{});
|
||||||
|
pub const fillText = bridge.function(OffscreenCanvasRenderingContext2D.fillText, .{});
|
||||||
|
pub const strokeText = bridge.function(OffscreenCanvasRenderingContext2D.strokeText, .{});
|
||||||
|
};
|
||||||
@@ -25,6 +25,7 @@ const HtmlElement = @import("../Html.zig");
|
|||||||
|
|
||||||
const CanvasRenderingContext2D = @import("../../canvas/CanvasRenderingContext2D.zig");
|
const CanvasRenderingContext2D = @import("../../canvas/CanvasRenderingContext2D.zig");
|
||||||
const WebGLRenderingContext = @import("../../canvas/WebGLRenderingContext.zig");
|
const WebGLRenderingContext = @import("../../canvas/WebGLRenderingContext.zig");
|
||||||
|
const OffscreenCanvas = @import("../../canvas/OffscreenCanvas.zig");
|
||||||
|
|
||||||
const Canvas = @This();
|
const Canvas = @This();
|
||||||
_proto: *HtmlElement,
|
_proto: *HtmlElement,
|
||||||
@@ -80,6 +81,14 @@ pub fn getContext(_: *Canvas, context_type: []const u8, page: *Page) !?DrawingCo
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Transfers control of the canvas to an OffscreenCanvas.
|
||||||
|
/// Returns an OffscreenCanvas with the same dimensions.
|
||||||
|
pub fn transferControlToOffscreen(self: *Canvas, page: *Page) !*OffscreenCanvas {
|
||||||
|
const width = self.getWidth();
|
||||||
|
const height = self.getHeight();
|
||||||
|
return OffscreenCanvas.constructor(width, height, page);
|
||||||
|
}
|
||||||
|
|
||||||
pub const JsApi = struct {
|
pub const JsApi = struct {
|
||||||
pub const bridge = js.Bridge(Canvas);
|
pub const bridge = js.Bridge(Canvas);
|
||||||
|
|
||||||
@@ -92,4 +101,5 @@ pub const JsApi = struct {
|
|||||||
pub const width = bridge.accessor(Canvas.getWidth, Canvas.setWidth, .{});
|
pub const width = bridge.accessor(Canvas.getWidth, Canvas.setWidth, .{});
|
||||||
pub const height = bridge.accessor(Canvas.getHeight, Canvas.setHeight, .{});
|
pub const height = bridge.accessor(Canvas.getHeight, Canvas.setHeight, .{});
|
||||||
pub const getContext = bridge.function(Canvas.getContext, .{});
|
pub const getContext = bridge.function(Canvas.getContext, .{});
|
||||||
|
pub const transferControlToOffscreen = bridge.function(Canvas.transferControlToOffscreen, .{});
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user