font: shapers init with allocator since web canvas needs to init buffer

This commit is contained in:
Mitchell Hashimoto
2022-12-06 13:39:18 -08:00
parent 760f0c057c
commit dd71456f35
4 changed files with 47 additions and 6 deletions

View File

@ -26,7 +26,10 @@ pub const Shaper = struct {
/// The cell_buf argument is the buffer to use for storing shaped results.
/// This should be at least the number of columns in the terminal.
pub fn init(cell_buf: []font.shape.Cell) !Shaper {
pub fn init(alloc: Allocator, cell_buf: []font.shape.Cell) !Shaper {
// Allocator is not used because harfbuzz uses libc
_ = alloc;
return Shaper{
.hb_buf = try harfbuzz.Buffer.create(),
.cell_buf = cell_buf,
@ -547,7 +550,7 @@ fn testShaper(alloc: Allocator) !TestShaper {
var cell_buf = try alloc.alloc(font.shape.Cell, 80);
errdefer alloc.free(cell_buf);
var shaper = try Shaper.init(cell_buf);
var shaper = try Shaper.init(alloc, cell_buf);
errdefer shaper.deinit();
return TestShaper{

View File

@ -2,24 +2,62 @@ const std = @import("std");
const assert = std.debug.assert;
const Allocator = std.mem.Allocator;
const font = @import("../main.zig");
const terminal = @import("../../terminal/main.zig");
const log = std.log.scoped(.font_shaper);
pub const Shaper = struct {
const RunBuf = std.ArrayList(u32);
/// The shared memory used for shaping results.
cell_buf: []font.shape.Cell,
/// The shared memory used for storing information about a run.
run_buf: RunBuf,
/// The cell_buf argument is the buffer to use for storing shaped results.
/// This should be at least the number of columns in the terminal.
pub fn init(cell_buf: []font.shape.Cell) !Shaper {
pub fn init(alloc: Allocator, cell_buf: []font.shape.Cell) !Shaper {
return Shaper{
.cell_buf = cell_buf,
.run_buf = try RunBuf.initCapacity(alloc, cell_buf.len),
};
}
pub fn deinit(self: *Shaper) void {
_ = self;
self.run_buf.deinit();
self.* = undefined;
}
/// Returns an iterator that returns one text run at a time for the
/// given terminal row. Note that text runs are are only valid one at a time
/// for a Shaper struct since they share state.
pub fn runIterator(
self: *Shaper,
group: *font.GroupCache,
row: terminal.Screen.Row,
) font.shape.RunIterator {
return .{ .hooks = .{ .shaper = self }, .group = group, .row = row };
}
/// The hooks for RunIterator.
pub const RunIteratorHook = struct {
shaper: *Shaper,
pub fn prepare(self: RunIteratorHook) !void {
// Reset the buffer for our current run
self.shaper.run_buf.clearRetainingCapacity();
}
pub fn addCodepoint(self: RunIteratorHook, cp: u32, cluster: u32) !void {
_ = cluster;
try self.shaper.append(cp);
}
pub fn finalize(self: RunIteratorHook) !void {
_ = self;
}
};
};
/// The wasm-compatible API.

View File

@ -180,7 +180,7 @@ pub fn init(alloc: Allocator, options: renderer.Options) !Metal {
// avoid allocations later.
var shape_buf = try alloc.alloc(font.shape.Cell, 160);
errdefer alloc.free(shape_buf);
var font_shaper = try font.Shaper.init(shape_buf);
var font_shaper = try font.Shaper.init(alloc, shape_buf);
errdefer font_shaper.deinit();
// Initialize our Metal buffers

View File

@ -162,7 +162,7 @@ pub fn init(alloc: Allocator, options: renderer.Options) !OpenGL {
// Create the initial font shaper
var shape_buf = try alloc.alloc(font.shape.Cell, 1);
errdefer alloc.free(shape_buf);
var shaper = try font.Shaper.init(shape_buf);
var shaper = try font.Shaper.init(alloc, shape_buf);
errdefer shaper.deinit();
// Create our shader