mirror of
https://github.com/ghostty-org/ghostty.git
synced 2025-07-14 15:56:13 +03:00
face: web canvas glyph rendering appears to work!
This commit is contained in:
@ -100,6 +100,8 @@ pub const Face = struct {
|
|||||||
glyph_index: u32,
|
glyph_index: u32,
|
||||||
max_height: ?u16,
|
max_height: ?u16,
|
||||||
) !font.Glyph {
|
) !font.Glyph {
|
||||||
|
_ = max_height;
|
||||||
|
|
||||||
// Encode our glyph into UTF-8 so we can build a JS string out of it.
|
// Encode our glyph into UTF-8 so we can build a JS string out of it.
|
||||||
var utf8: [4]u8 = undefined;
|
var utf8: [4]u8 = undefined;
|
||||||
const utf8_len = try std.unicode.utf8Encode(@intCast(u21, glyph_index), &utf8);
|
const utf8_len = try std.unicode.utf8Encode(@intCast(u21, glyph_index), &utf8);
|
||||||
@ -146,7 +148,9 @@ pub const Face = struct {
|
|||||||
const ctx = try self.context();
|
const ctx = try self.context();
|
||||||
defer ctx.deinit();
|
defer ctx.deinit();
|
||||||
|
|
||||||
// Set our alignment different since we want it centered exactly
|
// We use top alignment because our renderer handles all the
|
||||||
|
// baseline and so on so we just want a top-left rendered glyph
|
||||||
|
// by itself.
|
||||||
try ctx.set("textBaseline", js.string("top"));
|
try ctx.set("textBaseline", js.string("top"));
|
||||||
|
|
||||||
// Draw background
|
// Draw background
|
||||||
@ -162,13 +166,72 @@ pub const Face = struct {
|
|||||||
try ctx.set("fillStyle", js.string("black"));
|
try ctx.set("fillStyle", js.string("black"));
|
||||||
try ctx.call(void, "fillText", .{
|
try ctx.call(void, "fillText", .{
|
||||||
glyph_str,
|
glyph_str,
|
||||||
width / 2,
|
0,
|
||||||
height / 2,
|
0,
|
||||||
});
|
});
|
||||||
|
|
||||||
_ = atlas;
|
// Read the image data and get it into a []u8 on our side
|
||||||
_ = max_height;
|
const bitmap: []u8 = bitmap: {
|
||||||
return error.Unimplemented;
|
// Read the raw bitmap data and get the "data" value which is a
|
||||||
|
// Uint8ClampedArray.
|
||||||
|
const data = try ctx.call(js.Object, "getImageData", .{ 0, 0, width, height });
|
||||||
|
defer data.deinit();
|
||||||
|
const src_array = try data.get(js.Object, "data");
|
||||||
|
defer src_array.deinit();
|
||||||
|
|
||||||
|
// Allocate our local memory to copy the data to.
|
||||||
|
const len = try src_array.get(u32, "length");
|
||||||
|
var bitmap = try alloc.alloc(u8, @intCast(usize, len));
|
||||||
|
errdefer alloc.free(bitmap);
|
||||||
|
|
||||||
|
// Create our target Uint8Array that we can use to copy from src.
|
||||||
|
const mem_array = mem_array: {
|
||||||
|
// Get our runtime memory
|
||||||
|
const mem = try js.runtime.get(js.Object, "memory");
|
||||||
|
defer mem.deinit();
|
||||||
|
const buf = try mem.get(js.Object, "buffer");
|
||||||
|
defer buf.deinit();
|
||||||
|
|
||||||
|
// Construct our array to peer into our memory
|
||||||
|
const Uint8Array = try js.global.get(js.Object, "Uint8Array");
|
||||||
|
defer Uint8Array.deinit();
|
||||||
|
const mem_array = try Uint8Array.new(.{ buf, bitmap.ptr });
|
||||||
|
errdefer mem_array.deinit();
|
||||||
|
|
||||||
|
break :mem_array mem_array;
|
||||||
|
};
|
||||||
|
defer mem_array.deinit();
|
||||||
|
|
||||||
|
// Copy
|
||||||
|
try mem_array.call(void, "set", .{src_array});
|
||||||
|
|
||||||
|
break :bitmap bitmap;
|
||||||
|
};
|
||||||
|
defer alloc.free(bitmap);
|
||||||
|
|
||||||
|
// The bitmap is in RGBA format and we just want alpha8.
|
||||||
|
assert(@mod(bitmap.len, 4) == 0);
|
||||||
|
var bitmap_a8 = try alloc.alloc(u8, bitmap.len / 4);
|
||||||
|
defer alloc.free(bitmap_a8);
|
||||||
|
var i: usize = 0;
|
||||||
|
while (i < bitmap_a8.len) : (i += 1) {
|
||||||
|
bitmap_a8[i] = bitmap[i * 4];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Put it in our atlas
|
||||||
|
const region = try atlas.reserve(alloc, width, height);
|
||||||
|
if (region.width > 0 and region.height > 0) atlas.set(region, bitmap_a8);
|
||||||
|
|
||||||
|
return font.Glyph{
|
||||||
|
.width = width,
|
||||||
|
.height = height,
|
||||||
|
// TODO: this can't be right
|
||||||
|
.offset_x = 0,
|
||||||
|
.offset_y = 0,
|
||||||
|
.atlas_x = region.x,
|
||||||
|
.atlas_y = region.y,
|
||||||
|
.advance_x = 0,
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Calculate the metrics associated with a given face.
|
/// Calculate the metrics associated with a given face.
|
||||||
|
2
vendor/zig-js
vendored
2
vendor/zig-js
vendored
@ -1 +1 @@
|
|||||||
Subproject commit 3aebb1cbee374025368e223ef23b0c488ba612eb
|
Subproject commit 00eb5166ea3a070ac985b2b4409f2e51877865f4
|
Reference in New Issue
Block a user