diff --git a/build.zig b/build.zig index eba845825..d74933803 100644 --- a/build.zig +++ b/build.zig @@ -106,11 +106,11 @@ pub fn build(b: *std.build.Builder) !void { b.installFile("dist/macos/Ghostty.icns", "Ghostty.app/Contents/Resources/Ghostty.icns"); } - // term.wasm + // wasm { const wasm = b.addSharedLibrary( - "ghostty-term", - "src/terminal/main_wasm.zig", + "ghostty-wasm", + "src/main_wasm.zig", .{ .unversioned = {} }, ); wasm.setTarget(.{ .cpu_arch = .wasm32, .os_tag = .freestanding }); @@ -122,7 +122,7 @@ pub fn build(b: *std.build.Builder) !void { wasm.addPackage(utf8proc.pkg); _ = try utf8proc.link(b, wasm); - const step = b.step("term-wasm", "Build the terminal.wasm library"); + const step = b.step("wasm", "Build the wasm library"); step.dependOn(&wasm.step); } diff --git a/src/font/Atlas.zig b/src/font/Atlas.zig index 1bb8fb5f5..9bce5e7cb 100644 --- a/src/font/Atlas.zig +++ b/src/font/Atlas.zig @@ -76,7 +76,7 @@ pub const Error = error{ /// A region within the texture atlas. These can be acquired using the /// "reserve" function. A region reservation is required to write data. -pub const Region = struct { +pub const Region = extern struct { x: u32, y: u32, width: u32, @@ -298,6 +298,64 @@ pub fn clear(self: *Atlas) void { self.nodes.appendAssumeCapacity(.{ .x = 1, .y = 1, .width = self.size - 2 }); } +/// The wasm-compatible API. This lacks documentation unless the API differs +/// from the standard Zig API. To learn what a function does, just look one +/// level deeper to what Zig function is called and read the documentation there. +/// +/// To export this from Zig, use `usingnamespace Wasm` in some top-level +/// space and it will be exported. +pub const Wasm = struct { + // If you're copying this file (Atlas.zig) out to a separate project, + // just replace this with the allocator you want to use. + const wasm = @import("../wasm.zig"); + const alloc = wasm.alloc; + + const FormatInt = @typeInfo(Format).Enum.tag_type; + export const ATLAS_FORMAT_GREYSCALE: u8 = @enumToInt(Format.greyscale); + export const ATLAS_FORMAT_RGB: u8 = @enumToInt(Format.rgb); + export const ATLAS_FORMAT_RGBA: u8 = @enumToInt(Format.rgba); + + export fn atlas_new(size: u32, format: u8) ?*Atlas { + const atlas = init( + alloc, + size, + @intToEnum(Format, @intCast(FormatInt, format)), + ) catch return null; + const result = alloc.create(Atlas) catch return null; + result.* = atlas; + return result; + } + + export fn atlas_reserve(self: *Atlas, width: u32, height: u32) Region { + return self.reserve(alloc, width, height) catch .{ + .x = 0, + .y = 0, + .width = 0, + .height = 0, + }; + } + + export fn atlas_set(self: *Atlas, reg: Region, data: [*]const u8, len: usize) void { + self.set(reg, data[0..len]); + } + + export fn atlas_grow(self: *Atlas, size_new: u32) bool { + self.grow(alloc, size_new) catch return false; + return true; + } + + export fn atlas_clear(self: *Atlas) void { + self.clear(); + } + + export fn atlas_free(ptr: ?*Atlas) void { + if (ptr) |v| { + v.deinit(alloc); + alloc.destroy(v); + } + } +}; + test "exact fit" { const alloc = testing.allocator; var atlas = try init(alloc, 34, .greyscale); // +2 for 1px border diff --git a/src/font/main.zig b/src/font/main.zig index b6747faea..7f93c4299 100644 --- a/src/font/main.zig +++ b/src/font/main.zig @@ -1,4 +1,5 @@ const std = @import("std"); +const builtin = @import("builtin"); const build_options = @import("build_options"); pub const Atlas = @import("Atlas.zig"); @@ -16,6 +17,10 @@ pub const Sprite = sprite.Sprite; pub const Descriptor = discovery.Descriptor; pub const Discover = discovery.Discover; +pub usingnamespace if (builtin.target.isWasm()) struct { + pub usingnamespace Atlas.Wasm; +} else struct {}; + /// Build options pub const options: struct { backend: Backend, diff --git a/src/main_wasm.zig b/src/main_wasm.zig new file mode 100644 index 000000000..06fbe4456 --- /dev/null +++ b/src/main_wasm.zig @@ -0,0 +1,4 @@ +// This is the main file for the WASM module. The WASM module has to +// export a C ABI compatible API. + +pub usingnamespace @import("font/main.zig"); diff --git a/src/wasm.zig b/src/wasm.zig new file mode 100644 index 000000000..96b53e425 --- /dev/null +++ b/src/wasm.zig @@ -0,0 +1,5 @@ +//! This file contains helpers for wasm compilation. +const std = @import("std"); + +/// The allocator to use in wasm environments. +pub const alloc = std.heap.page_allocator;