mirror of
https://github.com/ghostty-org/ghostty.git
synced 2025-10-17 07:16:12 +00:00
move runIterator options to dedicated struct
This commit is contained in:
@@ -2,6 +2,9 @@ const builtin = @import("builtin");
|
||||
const options = @import("main.zig").options;
|
||||
const run = @import("shaper/run.zig");
|
||||
const feature = @import("shaper/feature.zig");
|
||||
const configpkg = @import("../config.zig");
|
||||
const terminal = @import("../terminal/main.zig");
|
||||
const SharedGrid = @import("main.zig").SharedGrid;
|
||||
pub const noop = @import("shaper/noop.zig");
|
||||
pub const harfbuzz = @import("shaper/harfbuzz.zig");
|
||||
pub const coretext = @import("shaper/coretext.zig");
|
||||
@@ -61,6 +64,38 @@ pub const Options = struct {
|
||||
features: []const []const u8 = &.{},
|
||||
};
|
||||
|
||||
/// Options for runIterator.
|
||||
pub const RunOptions = struct {
|
||||
/// The font state for the terminal screen. This is mutable because
|
||||
/// cached values may be updated during shaping.
|
||||
grid: *SharedGrid,
|
||||
|
||||
/// The terminal screen to shape.
|
||||
screen: *const terminal.Screen,
|
||||
|
||||
/// The row within the screen to shape. This row must exist within
|
||||
/// screen; it is not validated.
|
||||
row: terminal.Pin,
|
||||
|
||||
/// The selection boundaries. This is used to break shaping on
|
||||
/// selection boundaries. This can be disabled by setting this to
|
||||
/// null.
|
||||
selection: ?terminal.Selection = null,
|
||||
|
||||
/// The cursor position within this row. This is used to break shaping
|
||||
/// on cursor boundaries. This can be disabled by setting this to
|
||||
/// null.
|
||||
cursor_x: ?usize = null,
|
||||
|
||||
/// Apply the font break configuration to the run.
|
||||
pub fn applyBreakConfig(
|
||||
self: *RunOptions,
|
||||
config: configpkg.FontShapingBreak,
|
||||
) void {
|
||||
if (!config.cursor) self.cursor_x = null;
|
||||
}
|
||||
};
|
||||
|
||||
test {
|
||||
_ = Cache;
|
||||
_ = Shaper;
|
||||
|
@@ -289,21 +289,11 @@ pub const Shaper = struct {
|
||||
|
||||
pub fn runIterator(
|
||||
self: *Shaper,
|
||||
grid: *SharedGrid,
|
||||
screen: *const terminal.Screen,
|
||||
row: terminal.Pin,
|
||||
selection: ?terminal.Selection,
|
||||
cursor_x: ?usize,
|
||||
break_config: config.FontShapingBreak,
|
||||
opts: font.shape.RunOptions,
|
||||
) font.shape.RunIterator {
|
||||
return .{
|
||||
.hooks = .{ .shaper = self },
|
||||
.grid = grid,
|
||||
.screen = screen,
|
||||
.row = row,
|
||||
.selection = selection,
|
||||
.cursor_x = cursor_x,
|
||||
.break_config = break_config,
|
||||
.opts = opts,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -597,14 +587,11 @@ test "run iterator" {
|
||||
|
||||
// Get our run iterator
|
||||
var shaper = &testdata.shaper;
|
||||
var it = shaper.runIterator(
|
||||
testdata.grid,
|
||||
&screen,
|
||||
screen.pages.pin(.{ .screen = .{ .y = 0 } }).?,
|
||||
null,
|
||||
null,
|
||||
.{},
|
||||
);
|
||||
var it = shaper.runIterator(.{
|
||||
.grid = testdata.grid,
|
||||
.screen = &screen,
|
||||
.row = screen.pages.pin(.{ .screen = .{ .y = 0 } }).?,
|
||||
});
|
||||
var count: usize = 0;
|
||||
while (try it.next(alloc)) |_| count += 1;
|
||||
try testing.expectEqual(@as(usize, 1), count);
|
||||
@@ -617,14 +604,11 @@ test "run iterator" {
|
||||
try screen.testWriteString("ABCD EFG");
|
||||
|
||||
var shaper = &testdata.shaper;
|
||||
var it = shaper.runIterator(
|
||||
testdata.grid,
|
||||
&screen,
|
||||
screen.pages.pin(.{ .screen = .{ .y = 0 } }).?,
|
||||
null,
|
||||
null,
|
||||
.{},
|
||||
);
|
||||
var it = shaper.runIterator(.{
|
||||
.grid = testdata.grid,
|
||||
.screen = &screen,
|
||||
.row = screen.pages.pin(.{ .screen = .{ .y = 0 } }).?,
|
||||
});
|
||||
var count: usize = 0;
|
||||
while (try it.next(alloc)) |_| count += 1;
|
||||
try testing.expectEqual(@as(usize, 1), count);
|
||||
@@ -638,14 +622,11 @@ test "run iterator" {
|
||||
|
||||
// Get our run iterator
|
||||
var shaper = &testdata.shaper;
|
||||
var it = shaper.runIterator(
|
||||
testdata.grid,
|
||||
&screen,
|
||||
screen.pages.pin(.{ .screen = .{ .y = 0 } }).?,
|
||||
null,
|
||||
null,
|
||||
.{},
|
||||
);
|
||||
var it = shaper.runIterator(.{
|
||||
.grid = testdata.grid,
|
||||
.screen = &screen,
|
||||
.row = screen.pages.pin(.{ .screen = .{ .y = 0 } }).?,
|
||||
});
|
||||
var count: usize = 0;
|
||||
while (try it.next(alloc)) |_| count += 1;
|
||||
try testing.expectEqual(@as(usize, 3), count);
|
||||
@@ -660,14 +641,11 @@ test "run iterator" {
|
||||
|
||||
// Get our run iterator
|
||||
var shaper = &testdata.shaper;
|
||||
var it = shaper.runIterator(
|
||||
testdata.grid,
|
||||
&screen,
|
||||
screen.pages.pin(.{ .screen = .{ .y = 0 } }).?,
|
||||
null,
|
||||
null,
|
||||
.{},
|
||||
);
|
||||
var it = shaper.runIterator(.{
|
||||
.grid = testdata.grid,
|
||||
.screen = &screen,
|
||||
.row = screen.pages.pin(.{ .screen = .{ .y = 0 } }).?,
|
||||
});
|
||||
var count: usize = 0;
|
||||
while (try it.next(alloc)) |_| count += 1;
|
||||
try testing.expectEqual(@as(usize, 2), count);
|
||||
@@ -708,14 +686,11 @@ test "run iterator: empty cells with background set" {
|
||||
|
||||
// Get our run iterator
|
||||
var shaper = &testdata.shaper;
|
||||
var it = shaper.runIterator(
|
||||
testdata.grid,
|
||||
&screen,
|
||||
screen.pages.pin(.{ .screen = .{ .y = 0 } }).?,
|
||||
null,
|
||||
null,
|
||||
.{},
|
||||
);
|
||||
var it = shaper.runIterator(.{
|
||||
.grid = testdata.grid,
|
||||
.screen = &screen,
|
||||
.row = screen.pages.pin(.{ .screen = .{ .y = 0 } }).?,
|
||||
});
|
||||
{
|
||||
const run = (try it.next(alloc)).?;
|
||||
const cells = try shaper.shape(run);
|
||||
@@ -745,14 +720,11 @@ test "shape" {
|
||||
|
||||
// Get our run iterator
|
||||
var shaper = &testdata.shaper;
|
||||
var it = shaper.runIterator(
|
||||
testdata.grid,
|
||||
&screen,
|
||||
screen.pages.pin(.{ .screen = .{ .y = 0 } }).?,
|
||||
null,
|
||||
null,
|
||||
.{},
|
||||
);
|
||||
var it = shaper.runIterator(.{
|
||||
.grid = testdata.grid,
|
||||
.screen = &screen,
|
||||
.row = screen.pages.pin(.{ .screen = .{ .y = 0 } }).?,
|
||||
});
|
||||
var count: usize = 0;
|
||||
while (try it.next(alloc)) |run| {
|
||||
count += 1;
|
||||
@@ -781,14 +753,11 @@ test "shape nerd fonts" {
|
||||
|
||||
// Get our run iterator
|
||||
var shaper = &testdata.shaper;
|
||||
var it = shaper.runIterator(
|
||||
testdata.grid,
|
||||
&screen,
|
||||
screen.pages.pin(.{ .screen = .{ .y = 0 } }).?,
|
||||
null,
|
||||
null,
|
||||
.{},
|
||||
);
|
||||
var it = shaper.runIterator(.{
|
||||
.grid = testdata.grid,
|
||||
.screen = &screen,
|
||||
.row = screen.pages.pin(.{ .screen = .{ .y = 0 } }).?,
|
||||
});
|
||||
var count: usize = 0;
|
||||
while (try it.next(alloc)) |run| {
|
||||
count += 1;
|
||||
@@ -810,14 +779,11 @@ test "shape inconsolata ligs" {
|
||||
try screen.testWriteString(">=");
|
||||
|
||||
var shaper = &testdata.shaper;
|
||||
var it = shaper.runIterator(
|
||||
testdata.grid,
|
||||
&screen,
|
||||
screen.pages.pin(.{ .screen = .{ .y = 0 } }).?,
|
||||
null,
|
||||
null,
|
||||
.{},
|
||||
);
|
||||
var it = shaper.runIterator(.{
|
||||
.grid = testdata.grid,
|
||||
.screen = &screen,
|
||||
.row = screen.pages.pin(.{ .screen = .{ .y = 0 } }).?,
|
||||
});
|
||||
var count: usize = 0;
|
||||
while (try it.next(alloc)) |run| {
|
||||
count += 1;
|
||||
@@ -836,14 +802,11 @@ test "shape inconsolata ligs" {
|
||||
try screen.testWriteString("===");
|
||||
|
||||
var shaper = &testdata.shaper;
|
||||
var it = shaper.runIterator(
|
||||
testdata.grid,
|
||||
&screen,
|
||||
screen.pages.pin(.{ .screen = .{ .y = 0 } }).?,
|
||||
null,
|
||||
null,
|
||||
.{},
|
||||
);
|
||||
var it = shaper.runIterator(.{
|
||||
.grid = testdata.grid,
|
||||
.screen = &screen,
|
||||
.row = screen.pages.pin(.{ .screen = .{ .y = 0 } }).?,
|
||||
});
|
||||
var count: usize = 0;
|
||||
while (try it.next(alloc)) |run| {
|
||||
count += 1;
|
||||
@@ -870,14 +833,11 @@ test "shape monaspace ligs" {
|
||||
try screen.testWriteString("===");
|
||||
|
||||
var shaper = &testdata.shaper;
|
||||
var it = shaper.runIterator(
|
||||
testdata.grid,
|
||||
&screen,
|
||||
screen.pages.pin(.{ .screen = .{ .y = 0 } }).?,
|
||||
null,
|
||||
null,
|
||||
.{},
|
||||
);
|
||||
var it = shaper.runIterator(.{
|
||||
.grid = testdata.grid,
|
||||
.screen = &screen,
|
||||
.row = screen.pages.pin(.{ .screen = .{ .y = 0 } }).?,
|
||||
});
|
||||
var count: usize = 0;
|
||||
while (try it.next(alloc)) |run| {
|
||||
count += 1;
|
||||
@@ -905,14 +865,11 @@ test "shape left-replaced lig in last run" {
|
||||
try screen.testWriteString("!==");
|
||||
|
||||
var shaper = &testdata.shaper;
|
||||
var it = shaper.runIterator(
|
||||
testdata.grid,
|
||||
&screen,
|
||||
screen.pages.pin(.{ .screen = .{ .y = 0 } }).?,
|
||||
null,
|
||||
null,
|
||||
.{},
|
||||
);
|
||||
var it = shaper.runIterator(.{
|
||||
.grid = testdata.grid,
|
||||
.screen = &screen,
|
||||
.row = screen.pages.pin(.{ .screen = .{ .y = 0 } }).?,
|
||||
});
|
||||
var count: usize = 0;
|
||||
while (try it.next(alloc)) |run| {
|
||||
count += 1;
|
||||
@@ -940,14 +897,11 @@ test "shape left-replaced lig in early run" {
|
||||
try screen.testWriteString("!==X");
|
||||
|
||||
var shaper = &testdata.shaper;
|
||||
var it = shaper.runIterator(
|
||||
testdata.grid,
|
||||
&screen,
|
||||
screen.pages.pin(.{ .screen = .{ .y = 0 } }).?,
|
||||
null,
|
||||
null,
|
||||
.{},
|
||||
);
|
||||
var it = shaper.runIterator(.{
|
||||
.grid = testdata.grid,
|
||||
.screen = &screen,
|
||||
.row = screen.pages.pin(.{ .screen = .{ .y = 0 } }).?,
|
||||
});
|
||||
|
||||
const run = (try it.next(alloc)).?;
|
||||
|
||||
@@ -972,14 +926,11 @@ test "shape U+3C9 with JB Mono" {
|
||||
try screen.testWriteString("\u{03C9} foo");
|
||||
|
||||
var shaper = &testdata.shaper;
|
||||
var it = shaper.runIterator(
|
||||
testdata.grid,
|
||||
&screen,
|
||||
screen.pages.pin(.{ .screen = .{ .y = 0 } }).?,
|
||||
null,
|
||||
null,
|
||||
.{},
|
||||
);
|
||||
var it = shaper.runIterator(.{
|
||||
.grid = testdata.grid,
|
||||
.screen = &screen,
|
||||
.row = screen.pages.pin(.{ .screen = .{ .y = 0 } }).?,
|
||||
});
|
||||
|
||||
var run_count: usize = 0;
|
||||
var cell_count: usize = 0;
|
||||
@@ -1006,14 +957,11 @@ test "shape emoji width" {
|
||||
try screen.testWriteString("👍");
|
||||
|
||||
var shaper = &testdata.shaper;
|
||||
var it = shaper.runIterator(
|
||||
testdata.grid,
|
||||
&screen,
|
||||
screen.pages.pin(.{ .screen = .{ .y = 0 } }).?,
|
||||
null,
|
||||
null,
|
||||
.{},
|
||||
);
|
||||
var it = shaper.runIterator(.{
|
||||
.grid = testdata.grid,
|
||||
.screen = &screen,
|
||||
.row = screen.pages.pin(.{ .screen = .{ .y = 0 } }).?,
|
||||
});
|
||||
var count: usize = 0;
|
||||
while (try it.next(alloc)) |run| {
|
||||
count += 1;
|
||||
@@ -1057,14 +1005,11 @@ test "shape emoji width long" {
|
||||
|
||||
// Get our run iterator
|
||||
var shaper = &testdata.shaper;
|
||||
var it = shaper.runIterator(
|
||||
testdata.grid,
|
||||
&screen,
|
||||
screen.pages.pin(.{ .screen = .{ .y = 1 } }).?,
|
||||
null,
|
||||
null,
|
||||
.{},
|
||||
);
|
||||
var it = shaper.runIterator(.{
|
||||
.grid = testdata.grid,
|
||||
.screen = &screen,
|
||||
.row = screen.pages.pin(.{ .screen = .{ .y = 1 } }).?,
|
||||
});
|
||||
var count: usize = 0;
|
||||
while (try it.next(alloc)) |run| {
|
||||
count += 1;
|
||||
@@ -1094,14 +1039,11 @@ test "shape variation selector VS15" {
|
||||
|
||||
// Get our run iterator
|
||||
var shaper = &testdata.shaper;
|
||||
var it = shaper.runIterator(
|
||||
testdata.grid,
|
||||
&screen,
|
||||
screen.pages.pin(.{ .screen = .{ .y = 0 } }).?,
|
||||
null,
|
||||
null,
|
||||
.{},
|
||||
);
|
||||
var it = shaper.runIterator(.{
|
||||
.grid = testdata.grid,
|
||||
.screen = &screen,
|
||||
.row = screen.pages.pin(.{ .screen = .{ .y = 0 } }).?,
|
||||
});
|
||||
var count: usize = 0;
|
||||
while (try it.next(alloc)) |run| {
|
||||
count += 1;
|
||||
@@ -1130,14 +1072,11 @@ test "shape variation selector VS16" {
|
||||
|
||||
// Get our run iterator
|
||||
var shaper = &testdata.shaper;
|
||||
var it = shaper.runIterator(
|
||||
testdata.grid,
|
||||
&screen,
|
||||
screen.pages.pin(.{ .screen = .{ .y = 0 } }).?,
|
||||
null,
|
||||
null,
|
||||
.{},
|
||||
);
|
||||
var it = shaper.runIterator(.{
|
||||
.grid = testdata.grid,
|
||||
.screen = &screen,
|
||||
.row = screen.pages.pin(.{ .screen = .{ .y = 0 } }).?,
|
||||
});
|
||||
var count: usize = 0;
|
||||
while (try it.next(alloc)) |run| {
|
||||
count += 1;
|
||||
@@ -1163,14 +1102,11 @@ test "shape with empty cells in between" {
|
||||
|
||||
// Get our run iterator
|
||||
var shaper = &testdata.shaper;
|
||||
var it = shaper.runIterator(
|
||||
testdata.grid,
|
||||
&screen,
|
||||
screen.pages.pin(.{ .screen = .{ .y = 0 } }).?,
|
||||
null,
|
||||
null,
|
||||
.{},
|
||||
);
|
||||
var it = shaper.runIterator(.{
|
||||
.grid = testdata.grid,
|
||||
.screen = &screen,
|
||||
.row = screen.pages.pin(.{ .screen = .{ .y = 0 } }).?,
|
||||
});
|
||||
var count: usize = 0;
|
||||
while (try it.next(alloc)) |run| {
|
||||
count += 1;
|
||||
@@ -1202,14 +1138,11 @@ test "shape Chinese characters" {
|
||||
|
||||
// Get our run iterator
|
||||
var shaper = &testdata.shaper;
|
||||
var it = shaper.runIterator(
|
||||
testdata.grid,
|
||||
&screen,
|
||||
screen.pages.pin(.{ .screen = .{ .y = 0 } }).?,
|
||||
null,
|
||||
null,
|
||||
.{},
|
||||
);
|
||||
var it = shaper.runIterator(.{
|
||||
.grid = testdata.grid,
|
||||
.screen = &screen,
|
||||
.row = screen.pages.pin(.{ .screen = .{ .y = 0 } }).?,
|
||||
});
|
||||
var count: usize = 0;
|
||||
while (try it.next(alloc)) |run| {
|
||||
count += 1;
|
||||
@@ -1243,14 +1176,11 @@ test "shape box glyphs" {
|
||||
|
||||
// Get our run iterator
|
||||
var shaper = &testdata.shaper;
|
||||
var it = shaper.runIterator(
|
||||
testdata.grid,
|
||||
&screen,
|
||||
screen.pages.pin(.{ .screen = .{ .y = 0 } }).?,
|
||||
null,
|
||||
null,
|
||||
.{},
|
||||
);
|
||||
var it = shaper.runIterator(.{
|
||||
.grid = testdata.grid,
|
||||
.screen = &screen,
|
||||
.row = screen.pages.pin(.{ .screen = .{ .y = 0 } }).?,
|
||||
});
|
||||
var count: usize = 0;
|
||||
while (try it.next(alloc)) |run| {
|
||||
count += 1;
|
||||
@@ -1280,18 +1210,16 @@ test "shape selection boundary" {
|
||||
{
|
||||
// Get our run iterator
|
||||
var shaper = &testdata.shaper;
|
||||
var it = shaper.runIterator(
|
||||
testdata.grid,
|
||||
&screen,
|
||||
screen.pages.pin(.{ .screen = .{ .y = 0 } }).?,
|
||||
terminal.Selection.init(
|
||||
var it = shaper.runIterator(.{
|
||||
.grid = testdata.grid,
|
||||
.screen = &screen,
|
||||
.row = screen.pages.pin(.{ .screen = .{ .y = 0 } }).?,
|
||||
.selection = terminal.Selection.init(
|
||||
screen.pages.pin(.{ .active = .{ .x = 0, .y = 0 } }).?,
|
||||
screen.pages.pin(.{ .active = .{ .x = screen.pages.cols - 1, .y = 0 } }).?,
|
||||
false,
|
||||
),
|
||||
null,
|
||||
.{},
|
||||
);
|
||||
});
|
||||
var count: usize = 0;
|
||||
while (try it.next(alloc)) |run| {
|
||||
count += 1;
|
||||
@@ -1304,18 +1232,16 @@ test "shape selection boundary" {
|
||||
{
|
||||
// Get our run iterator
|
||||
var shaper = &testdata.shaper;
|
||||
var it = shaper.runIterator(
|
||||
testdata.grid,
|
||||
&screen,
|
||||
screen.pages.pin(.{ .screen = .{ .y = 0 } }).?,
|
||||
terminal.Selection.init(
|
||||
var it = shaper.runIterator(.{
|
||||
.grid = testdata.grid,
|
||||
.screen = &screen,
|
||||
.row = screen.pages.pin(.{ .screen = .{ .y = 0 } }).?,
|
||||
.selection = terminal.Selection.init(
|
||||
screen.pages.pin(.{ .active = .{ .x = 2, .y = 0 } }).?,
|
||||
screen.pages.pin(.{ .active = .{ .x = screen.pages.cols - 1, .y = 0 } }).?,
|
||||
false,
|
||||
),
|
||||
null,
|
||||
.{},
|
||||
);
|
||||
});
|
||||
var count: usize = 0;
|
||||
while (try it.next(alloc)) |run| {
|
||||
count += 1;
|
||||
@@ -1328,18 +1254,16 @@ test "shape selection boundary" {
|
||||
{
|
||||
// Get our run iterator
|
||||
var shaper = &testdata.shaper;
|
||||
var it = shaper.runIterator(
|
||||
testdata.grid,
|
||||
&screen,
|
||||
screen.pages.pin(.{ .screen = .{ .y = 0 } }).?,
|
||||
terminal.Selection.init(
|
||||
var it = shaper.runIterator(.{
|
||||
.grid = testdata.grid,
|
||||
.screen = &screen,
|
||||
.row = screen.pages.pin(.{ .screen = .{ .y = 0 } }).?,
|
||||
.selection = terminal.Selection.init(
|
||||
screen.pages.pin(.{ .active = .{ .x = 0, .y = 0 } }).?,
|
||||
screen.pages.pin(.{ .active = .{ .x = 3, .y = 0 } }).?,
|
||||
false,
|
||||
),
|
||||
null,
|
||||
.{},
|
||||
);
|
||||
});
|
||||
var count: usize = 0;
|
||||
while (try it.next(alloc)) |run| {
|
||||
count += 1;
|
||||
@@ -1352,18 +1276,16 @@ test "shape selection boundary" {
|
||||
{
|
||||
// Get our run iterator
|
||||
var shaper = &testdata.shaper;
|
||||
var it = shaper.runIterator(
|
||||
testdata.grid,
|
||||
&screen,
|
||||
screen.pages.pin(.{ .screen = .{ .y = 0 } }).?,
|
||||
terminal.Selection.init(
|
||||
var it = shaper.runIterator(.{
|
||||
.grid = testdata.grid,
|
||||
.screen = &screen,
|
||||
.row = screen.pages.pin(.{ .screen = .{ .y = 0 } }).?,
|
||||
.selection = terminal.Selection.init(
|
||||
screen.pages.pin(.{ .active = .{ .x = 1, .y = 0 } }).?,
|
||||
screen.pages.pin(.{ .active = .{ .x = 3, .y = 0 } }).?,
|
||||
false,
|
||||
),
|
||||
null,
|
||||
.{},
|
||||
);
|
||||
});
|
||||
var count: usize = 0;
|
||||
while (try it.next(alloc)) |run| {
|
||||
count += 1;
|
||||
@@ -1376,18 +1298,16 @@ test "shape selection boundary" {
|
||||
{
|
||||
// Get our run iterator
|
||||
var shaper = &testdata.shaper;
|
||||
var it = shaper.runIterator(
|
||||
testdata.grid,
|
||||
&screen,
|
||||
screen.pages.pin(.{ .screen = .{ .y = 0 } }).?,
|
||||
terminal.Selection.init(
|
||||
var it = shaper.runIterator(.{
|
||||
.grid = testdata.grid,
|
||||
.screen = &screen,
|
||||
.row = screen.pages.pin(.{ .screen = .{ .y = 0 } }).?,
|
||||
.selection = terminal.Selection.init(
|
||||
screen.pages.pin(.{ .active = .{ .x = 1, .y = 0 } }).?,
|
||||
screen.pages.pin(.{ .active = .{ .x = 1, .y = 0 } }).?,
|
||||
false,
|
||||
),
|
||||
null,
|
||||
.{},
|
||||
);
|
||||
});
|
||||
var count: usize = 0;
|
||||
while (try it.next(alloc)) |run| {
|
||||
count += 1;
|
||||
@@ -1413,14 +1333,11 @@ test "shape cursor boundary" {
|
||||
{
|
||||
// Get our run iterator
|
||||
var shaper = &testdata.shaper;
|
||||
var it = shaper.runIterator(
|
||||
testdata.grid,
|
||||
&screen,
|
||||
screen.pages.pin(.{ .screen = .{ .y = 0 } }).?,
|
||||
null,
|
||||
null,
|
||||
.{},
|
||||
);
|
||||
var it = shaper.runIterator(.{
|
||||
.grid = testdata.grid,
|
||||
.screen = &screen,
|
||||
.row = screen.pages.pin(.{ .screen = .{ .y = 0 } }).?,
|
||||
});
|
||||
var count: usize = 0;
|
||||
while (try it.next(alloc)) |run| {
|
||||
count += 1;
|
||||
@@ -1434,14 +1351,12 @@ test "shape cursor boundary" {
|
||||
{
|
||||
// Get our run iterator
|
||||
var shaper = &testdata.shaper;
|
||||
var it = shaper.runIterator(
|
||||
testdata.grid,
|
||||
&screen,
|
||||
screen.pages.pin(.{ .screen = .{ .y = 0 } }).?,
|
||||
null,
|
||||
0,
|
||||
.{ .cursor = true },
|
||||
);
|
||||
var it = shaper.runIterator(.{
|
||||
.grid = testdata.grid,
|
||||
.screen = &screen,
|
||||
.row = screen.pages.pin(.{ .screen = .{ .y = 0 } }).?,
|
||||
.cursor_x = 0,
|
||||
});
|
||||
var count: usize = 0;
|
||||
while (try it.next(alloc)) |run| {
|
||||
count += 1;
|
||||
@@ -1453,14 +1368,11 @@ test "shape cursor boundary" {
|
||||
{
|
||||
// Get our run iterator
|
||||
var shaper = &testdata.shaper;
|
||||
var it = shaper.runIterator(
|
||||
testdata.grid,
|
||||
&screen,
|
||||
screen.pages.pin(.{ .screen = .{ .y = 0 } }).?,
|
||||
null,
|
||||
0,
|
||||
.{ .cursor = false },
|
||||
);
|
||||
var it = shaper.runIterator(.{
|
||||
.grid = testdata.grid,
|
||||
.screen = &screen,
|
||||
.row = screen.pages.pin(.{ .screen = .{ .y = 0 } }).?,
|
||||
});
|
||||
var count: usize = 0;
|
||||
while (try it.next(alloc)) |run| {
|
||||
count += 1;
|
||||
@@ -1475,14 +1387,12 @@ test "shape cursor boundary" {
|
||||
{
|
||||
// Get our run iterator
|
||||
var shaper = &testdata.shaper;
|
||||
var it = shaper.runIterator(
|
||||
testdata.grid,
|
||||
&screen,
|
||||
screen.pages.pin(.{ .screen = .{ .y = 0 } }).?,
|
||||
null,
|
||||
1,
|
||||
.{ .cursor = true },
|
||||
);
|
||||
var it = shaper.runIterator(.{
|
||||
.grid = testdata.grid,
|
||||
.screen = &screen,
|
||||
.row = screen.pages.pin(.{ .screen = .{ .y = 0 } }).?,
|
||||
.cursor_x = 1,
|
||||
});
|
||||
var count: usize = 0;
|
||||
while (try it.next(alloc)) |run| {
|
||||
count += 1;
|
||||
@@ -1494,14 +1404,11 @@ test "shape cursor boundary" {
|
||||
{
|
||||
// Get our run iterator
|
||||
var shaper = &testdata.shaper;
|
||||
var it = shaper.runIterator(
|
||||
testdata.grid,
|
||||
&screen,
|
||||
screen.pages.pin(.{ .screen = .{ .y = 0 } }).?,
|
||||
null,
|
||||
1,
|
||||
.{ .cursor = false },
|
||||
);
|
||||
var it = shaper.runIterator(.{
|
||||
.grid = testdata.grid,
|
||||
.screen = &screen,
|
||||
.row = screen.pages.pin(.{ .screen = .{ .y = 0 } }).?,
|
||||
});
|
||||
var count: usize = 0;
|
||||
while (try it.next(alloc)) |run| {
|
||||
count += 1;
|
||||
@@ -1515,14 +1422,12 @@ test "shape cursor boundary" {
|
||||
{
|
||||
// Get our run iterator
|
||||
var shaper = &testdata.shaper;
|
||||
var it = shaper.runIterator(
|
||||
testdata.grid,
|
||||
&screen,
|
||||
screen.pages.pin(.{ .screen = .{ .y = 0 } }).?,
|
||||
null,
|
||||
9,
|
||||
.{ .cursor = true },
|
||||
);
|
||||
var it = shaper.runIterator(.{
|
||||
.grid = testdata.grid,
|
||||
.screen = &screen,
|
||||
.row = screen.pages.pin(.{ .screen = .{ .y = 0 } }).?,
|
||||
.cursor_x = 9,
|
||||
});
|
||||
var count: usize = 0;
|
||||
while (try it.next(alloc)) |run| {
|
||||
count += 1;
|
||||
@@ -1534,14 +1439,11 @@ test "shape cursor boundary" {
|
||||
{
|
||||
// Get our run iterator
|
||||
var shaper = &testdata.shaper;
|
||||
var it = shaper.runIterator(
|
||||
testdata.grid,
|
||||
&screen,
|
||||
screen.pages.pin(.{ .screen = .{ .y = 0 } }).?,
|
||||
null,
|
||||
9,
|
||||
.{ .cursor = false },
|
||||
);
|
||||
var it = shaper.runIterator(.{
|
||||
.grid = testdata.grid,
|
||||
.screen = &screen,
|
||||
.row = screen.pages.pin(.{ .screen = .{ .y = 0 } }).?,
|
||||
});
|
||||
var count: usize = 0;
|
||||
while (try it.next(alloc)) |run| {
|
||||
count += 1;
|
||||
@@ -1568,14 +1470,11 @@ test "shape cursor boundary and colored emoji" {
|
||||
{
|
||||
// Get our run iterator
|
||||
var shaper = &testdata.shaper;
|
||||
var it = shaper.runIterator(
|
||||
testdata.grid,
|
||||
&screen,
|
||||
screen.pages.pin(.{ .screen = .{ .y = 0 } }).?,
|
||||
null,
|
||||
null,
|
||||
.{},
|
||||
);
|
||||
var it = shaper.runIterator(.{
|
||||
.grid = testdata.grid,
|
||||
.screen = &screen,
|
||||
.row = screen.pages.pin(.{ .screen = .{ .y = 0 } }).?,
|
||||
});
|
||||
var count: usize = 0;
|
||||
while (try it.next(alloc)) |run| {
|
||||
count += 1;
|
||||
@@ -1588,14 +1487,12 @@ test "shape cursor boundary and colored emoji" {
|
||||
{
|
||||
// Get our run iterator
|
||||
var shaper = &testdata.shaper;
|
||||
var it = shaper.runIterator(
|
||||
testdata.grid,
|
||||
&screen,
|
||||
screen.pages.pin(.{ .screen = .{ .y = 0 } }).?,
|
||||
null,
|
||||
0,
|
||||
.{},
|
||||
);
|
||||
var it = shaper.runIterator(.{
|
||||
.grid = testdata.grid,
|
||||
.screen = &screen,
|
||||
.row = screen.pages.pin(.{ .screen = .{ .y = 0 } }).?,
|
||||
.cursor_x = 0,
|
||||
});
|
||||
var count: usize = 0;
|
||||
while (try it.next(alloc)) |run| {
|
||||
count += 1;
|
||||
@@ -1606,14 +1503,11 @@ test "shape cursor boundary and colored emoji" {
|
||||
{
|
||||
// Get our run iterator
|
||||
var shaper = &testdata.shaper;
|
||||
var it = shaper.runIterator(
|
||||
testdata.grid,
|
||||
&screen,
|
||||
screen.pages.pin(.{ .screen = .{ .y = 0 } }).?,
|
||||
null,
|
||||
0,
|
||||
.{ .cursor = false },
|
||||
);
|
||||
var it = shaper.runIterator(.{
|
||||
.grid = testdata.grid,
|
||||
.screen = &screen,
|
||||
.row = screen.pages.pin(.{ .screen = .{ .y = 0 } }).?,
|
||||
});
|
||||
var count: usize = 0;
|
||||
while (try it.next(alloc)) |run| {
|
||||
count += 1;
|
||||
@@ -1624,14 +1518,12 @@ test "shape cursor boundary and colored emoji" {
|
||||
{
|
||||
// Get our run iterator
|
||||
var shaper = &testdata.shaper;
|
||||
var it = shaper.runIterator(
|
||||
testdata.grid,
|
||||
&screen,
|
||||
screen.pages.pin(.{ .screen = .{ .y = 0 } }).?,
|
||||
null,
|
||||
1,
|
||||
.{},
|
||||
);
|
||||
var it = shaper.runIterator(.{
|
||||
.grid = testdata.grid,
|
||||
.screen = &screen,
|
||||
.row = screen.pages.pin(.{ .screen = .{ .y = 0 } }).?,
|
||||
.cursor_x = 1,
|
||||
});
|
||||
var count: usize = 0;
|
||||
while (try it.next(alloc)) |run| {
|
||||
count += 1;
|
||||
@@ -1642,14 +1534,11 @@ test "shape cursor boundary and colored emoji" {
|
||||
{
|
||||
// Get our run iterator
|
||||
var shaper = &testdata.shaper;
|
||||
var it = shaper.runIterator(
|
||||
testdata.grid,
|
||||
&screen,
|
||||
screen.pages.pin(.{ .screen = .{ .y = 0 } }).?,
|
||||
null,
|
||||
1,
|
||||
.{ .cursor = false },
|
||||
);
|
||||
var it = shaper.runIterator(.{
|
||||
.grid = testdata.grid,
|
||||
.screen = &screen,
|
||||
.row = screen.pages.pin(.{ .screen = .{ .y = 0 } }).?,
|
||||
});
|
||||
var count: usize = 0;
|
||||
while (try it.next(alloc)) |run| {
|
||||
count += 1;
|
||||
@@ -1673,14 +1562,11 @@ test "shape cell attribute change" {
|
||||
try screen.testWriteString(">=");
|
||||
|
||||
var shaper = &testdata.shaper;
|
||||
var it = shaper.runIterator(
|
||||
testdata.grid,
|
||||
&screen,
|
||||
screen.pages.pin(.{ .screen = .{ .y = 0 } }).?,
|
||||
null,
|
||||
null,
|
||||
.{},
|
||||
);
|
||||
var it = shaper.runIterator(.{
|
||||
.grid = testdata.grid,
|
||||
.screen = &screen,
|
||||
.row = screen.pages.pin(.{ .screen = .{ .y = 0 } }).?,
|
||||
});
|
||||
var count: usize = 0;
|
||||
while (try it.next(alloc)) |run| {
|
||||
count += 1;
|
||||
@@ -1698,14 +1584,11 @@ test "shape cell attribute change" {
|
||||
try screen.testWriteString("=");
|
||||
|
||||
var shaper = &testdata.shaper;
|
||||
var it = shaper.runIterator(
|
||||
testdata.grid,
|
||||
&screen,
|
||||
screen.pages.pin(.{ .screen = .{ .y = 0 } }).?,
|
||||
null,
|
||||
null,
|
||||
.{},
|
||||
);
|
||||
var it = shaper.runIterator(.{
|
||||
.grid = testdata.grid,
|
||||
.screen = &screen,
|
||||
.row = screen.pages.pin(.{ .screen = .{ .y = 0 } }).?,
|
||||
});
|
||||
var count: usize = 0;
|
||||
while (try it.next(alloc)) |run| {
|
||||
count += 1;
|
||||
@@ -1724,14 +1607,11 @@ test "shape cell attribute change" {
|
||||
try screen.testWriteString("=");
|
||||
|
||||
var shaper = &testdata.shaper;
|
||||
var it = shaper.runIterator(
|
||||
testdata.grid,
|
||||
&screen,
|
||||
screen.pages.pin(.{ .screen = .{ .y = 0 } }).?,
|
||||
null,
|
||||
null,
|
||||
.{},
|
||||
);
|
||||
var it = shaper.runIterator(.{
|
||||
.grid = testdata.grid,
|
||||
.screen = &screen,
|
||||
.row = screen.pages.pin(.{ .screen = .{ .y = 0 } }).?,
|
||||
});
|
||||
var count: usize = 0;
|
||||
while (try it.next(alloc)) |run| {
|
||||
count += 1;
|
||||
@@ -1750,14 +1630,11 @@ test "shape cell attribute change" {
|
||||
try screen.testWriteString("=");
|
||||
|
||||
var shaper = &testdata.shaper;
|
||||
var it = shaper.runIterator(
|
||||
testdata.grid,
|
||||
&screen,
|
||||
screen.pages.pin(.{ .screen = .{ .y = 0 } }).?,
|
||||
null,
|
||||
null,
|
||||
.{},
|
||||
);
|
||||
var it = shaper.runIterator(.{
|
||||
.grid = testdata.grid,
|
||||
.screen = &screen,
|
||||
.row = screen.pages.pin(.{ .screen = .{ .y = 0 } }).?,
|
||||
});
|
||||
var count: usize = 0;
|
||||
while (try it.next(alloc)) |run| {
|
||||
count += 1;
|
||||
@@ -1775,14 +1652,11 @@ test "shape cell attribute change" {
|
||||
try screen.testWriteString("=");
|
||||
|
||||
var shaper = &testdata.shaper;
|
||||
var it = shaper.runIterator(
|
||||
testdata.grid,
|
||||
&screen,
|
||||
screen.pages.pin(.{ .screen = .{ .y = 0 } }).?,
|
||||
null,
|
||||
null,
|
||||
.{},
|
||||
);
|
||||
var it = shaper.runIterator(.{
|
||||
.grid = testdata.grid,
|
||||
.screen = &screen,
|
||||
.row = screen.pages.pin(.{ .screen = .{ .y = 0 } }).?,
|
||||
});
|
||||
var count: usize = 0;
|
||||
while (try it.next(alloc)) |run| {
|
||||
count += 1;
|
||||
@@ -1816,14 +1690,11 @@ test "shape high plane sprite font codepoint" {
|
||||
try screen.testWriteString("\u{1FB70}");
|
||||
|
||||
var shaper = &testdata.shaper;
|
||||
var it = shaper.runIterator(
|
||||
testdata.grid,
|
||||
&screen,
|
||||
screen.pages.pin(.{ .screen = .{ .y = 0 } }).?,
|
||||
null,
|
||||
null,
|
||||
.{},
|
||||
);
|
||||
var it = shaper.runIterator(.{
|
||||
.grid = testdata.grid,
|
||||
.screen = &screen,
|
||||
.row = screen.pages.pin(.{ .screen = .{ .y = 0 } }).?,
|
||||
});
|
||||
// We should get one run
|
||||
const run = (try it.next(alloc)).?;
|
||||
// The run state should have the UTF-16 encoding of the character.
|
||||
|
@@ -90,21 +90,11 @@ pub const Shaper = struct {
|
||||
/// and assume the y value matches.
|
||||
pub fn runIterator(
|
||||
self: *Shaper,
|
||||
grid: *SharedGrid,
|
||||
screen: *const terminal.Screen,
|
||||
row: terminal.Pin,
|
||||
selection: ?terminal.Selection,
|
||||
cursor_x: ?usize,
|
||||
break_config: config.FontShapingBreak,
|
||||
opts: font.shape.RunOptions,
|
||||
) font.shape.RunIterator {
|
||||
return .{
|
||||
.hooks = .{ .shaper = self },
|
||||
.grid = grid,
|
||||
.screen = screen,
|
||||
.row = row,
|
||||
.selection = selection,
|
||||
.cursor_x = cursor_x,
|
||||
.break_config = break_config,
|
||||
.opts = opts,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -228,14 +218,11 @@ test "run iterator" {
|
||||
|
||||
// Get our run iterator
|
||||
var shaper = &testdata.shaper;
|
||||
var it = shaper.runIterator(
|
||||
testdata.grid,
|
||||
&screen,
|
||||
screen.pages.pin(.{ .screen = .{ .y = 0 } }).?,
|
||||
null,
|
||||
null,
|
||||
.{},
|
||||
);
|
||||
var it = shaper.runIterator(.{
|
||||
.grid = testdata.grid,
|
||||
.screen = &screen,
|
||||
.row = screen.pages.pin(.{ .screen = .{ .y = 0 } }).?,
|
||||
});
|
||||
var count: usize = 0;
|
||||
while (try it.next(alloc)) |_| count += 1;
|
||||
try testing.expectEqual(@as(usize, 1), count);
|
||||
@@ -248,14 +235,11 @@ test "run iterator" {
|
||||
try screen.testWriteString("ABCD EFG");
|
||||
|
||||
var shaper = &testdata.shaper;
|
||||
var it = shaper.runIterator(
|
||||
testdata.grid,
|
||||
&screen,
|
||||
screen.pages.pin(.{ .screen = .{ .y = 0 } }).?,
|
||||
null,
|
||||
null,
|
||||
.{},
|
||||
);
|
||||
var it = shaper.runIterator(.{
|
||||
.grid = testdata.grid,
|
||||
.screen = &screen,
|
||||
.row = screen.pages.pin(.{ .screen = .{ .y = 0 } }).?,
|
||||
});
|
||||
var count: usize = 0;
|
||||
while (try it.next(alloc)) |_| count += 1;
|
||||
try testing.expectEqual(@as(usize, 1), count);
|
||||
@@ -269,14 +253,11 @@ test "run iterator" {
|
||||
|
||||
// Get our run iterator
|
||||
var shaper = &testdata.shaper;
|
||||
var it = shaper.runIterator(
|
||||
testdata.grid,
|
||||
&screen,
|
||||
screen.pages.pin(.{ .screen = .{ .y = 0 } }).?,
|
||||
null,
|
||||
null,
|
||||
.{},
|
||||
);
|
||||
var it = shaper.runIterator(.{
|
||||
.grid = testdata.grid,
|
||||
.screen = &screen,
|
||||
.row = screen.pages.pin(.{ .screen = .{ .y = 0 } }).?,
|
||||
});
|
||||
var count: usize = 0;
|
||||
while (try it.next(alloc)) |_| {
|
||||
count += 1;
|
||||
@@ -322,14 +303,11 @@ test "run iterator: empty cells with background set" {
|
||||
|
||||
// Get our run iterator
|
||||
var shaper = &testdata.shaper;
|
||||
var it = shaper.runIterator(
|
||||
testdata.grid,
|
||||
&screen,
|
||||
screen.pages.pin(.{ .screen = .{ .y = 0 } }).?,
|
||||
null,
|
||||
null,
|
||||
.{},
|
||||
);
|
||||
var it = shaper.runIterator(.{
|
||||
.grid = testdata.grid,
|
||||
.screen = &screen,
|
||||
.row = screen.pages.pin(.{ .screen = .{ .y = 0 } }).?,
|
||||
});
|
||||
{
|
||||
const run = (try it.next(alloc)).?;
|
||||
try testing.expectEqual(@as(u32, 3), shaper.hb_buf.getLength());
|
||||
@@ -360,14 +338,11 @@ test "shape" {
|
||||
|
||||
// Get our run iterator
|
||||
var shaper = &testdata.shaper;
|
||||
var it = shaper.runIterator(
|
||||
testdata.grid,
|
||||
&screen,
|
||||
screen.pages.pin(.{ .screen = .{ .y = 0 } }).?,
|
||||
null,
|
||||
null,
|
||||
.{},
|
||||
);
|
||||
var it = shaper.runIterator(.{
|
||||
.grid = testdata.grid,
|
||||
.screen = &screen,
|
||||
.row = screen.pages.pin(.{ .screen = .{ .y = 0 } }).?,
|
||||
});
|
||||
var count: usize = 0;
|
||||
while (try it.next(alloc)) |run| {
|
||||
count += 1;
|
||||
@@ -390,14 +365,11 @@ test "shape inconsolata ligs" {
|
||||
try screen.testWriteString(">=");
|
||||
|
||||
var shaper = &testdata.shaper;
|
||||
var it = shaper.runIterator(
|
||||
testdata.grid,
|
||||
&screen,
|
||||
screen.pages.pin(.{ .screen = .{ .y = 0 } }).?,
|
||||
null,
|
||||
null,
|
||||
.{},
|
||||
);
|
||||
var it = shaper.runIterator(.{
|
||||
.grid = testdata.grid,
|
||||
.screen = &screen,
|
||||
.row = screen.pages.pin(.{ .screen = .{ .y = 0 } }).?,
|
||||
});
|
||||
var count: usize = 0;
|
||||
while (try it.next(alloc)) |run| {
|
||||
count += 1;
|
||||
@@ -416,14 +388,11 @@ test "shape inconsolata ligs" {
|
||||
try screen.testWriteString("===");
|
||||
|
||||
var shaper = &testdata.shaper;
|
||||
var it = shaper.runIterator(
|
||||
testdata.grid,
|
||||
&screen,
|
||||
screen.pages.pin(.{ .screen = .{ .y = 0 } }).?,
|
||||
null,
|
||||
null,
|
||||
.{},
|
||||
);
|
||||
var it = shaper.runIterator(.{
|
||||
.grid = testdata.grid,
|
||||
.screen = &screen,
|
||||
.row = screen.pages.pin(.{ .screen = .{ .y = 0 } }).?,
|
||||
});
|
||||
var count: usize = 0;
|
||||
while (try it.next(alloc)) |run| {
|
||||
count += 1;
|
||||
@@ -450,14 +419,11 @@ test "shape monaspace ligs" {
|
||||
try screen.testWriteString("===");
|
||||
|
||||
var shaper = &testdata.shaper;
|
||||
var it = shaper.runIterator(
|
||||
testdata.grid,
|
||||
&screen,
|
||||
screen.pages.pin(.{ .screen = .{ .y = 0 } }).?,
|
||||
null,
|
||||
null,
|
||||
.{},
|
||||
);
|
||||
var it = shaper.runIterator(.{
|
||||
.grid = testdata.grid,
|
||||
.screen = &screen,
|
||||
.row = screen.pages.pin(.{ .screen = .{ .y = 0 } }).?,
|
||||
});
|
||||
var count: usize = 0;
|
||||
while (try it.next(alloc)) |run| {
|
||||
count += 1;
|
||||
@@ -487,14 +453,11 @@ test "shape arabic forced LTR" {
|
||||
try screen.testWriteString(@embedFile("testdata/arabic.txt"));
|
||||
|
||||
var shaper = &testdata.shaper;
|
||||
var it = shaper.runIterator(
|
||||
testdata.grid,
|
||||
&screen,
|
||||
screen.pages.pin(.{ .screen = .{ .y = 0 } }).?,
|
||||
null,
|
||||
null,
|
||||
.{},
|
||||
);
|
||||
var it = shaper.runIterator(.{
|
||||
.grid = testdata.grid,
|
||||
.screen = &screen,
|
||||
.row = screen.pages.pin(.{ .screen = .{ .y = 0 } }).?,
|
||||
});
|
||||
var count: usize = 0;
|
||||
while (try it.next(alloc)) |run| {
|
||||
count += 1;
|
||||
@@ -525,14 +488,11 @@ test "shape emoji width" {
|
||||
try screen.testWriteString("👍");
|
||||
|
||||
var shaper = &testdata.shaper;
|
||||
var it = shaper.runIterator(
|
||||
testdata.grid,
|
||||
&screen,
|
||||
screen.pages.pin(.{ .screen = .{ .y = 0 } }).?,
|
||||
null,
|
||||
null,
|
||||
.{},
|
||||
);
|
||||
var it = shaper.runIterator(.{
|
||||
.grid = testdata.grid,
|
||||
.screen = &screen,
|
||||
.row = screen.pages.pin(.{ .screen = .{ .y = 0 } }).?,
|
||||
});
|
||||
var count: usize = 0;
|
||||
while (try it.next(alloc)) |run| {
|
||||
count += 1;
|
||||
@@ -578,14 +538,11 @@ test "shape emoji width long" {
|
||||
|
||||
// Get our run iterator
|
||||
var shaper = &testdata.shaper;
|
||||
var it = shaper.runIterator(
|
||||
testdata.grid,
|
||||
&screen,
|
||||
screen.pages.pin(.{ .screen = .{ .y = 1 } }).?,
|
||||
null,
|
||||
null,
|
||||
.{},
|
||||
);
|
||||
var it = shaper.runIterator(.{
|
||||
.grid = testdata.grid,
|
||||
.screen = &screen,
|
||||
.row = screen.pages.pin(.{ .screen = .{ .y = 1 } }).?,
|
||||
});
|
||||
var count: usize = 0;
|
||||
while (try it.next(alloc)) |run| {
|
||||
count += 1;
|
||||
@@ -617,14 +574,11 @@ test "shape variation selector VS15" {
|
||||
|
||||
// Get our run iterator
|
||||
var shaper = &testdata.shaper;
|
||||
var it = shaper.runIterator(
|
||||
testdata.grid,
|
||||
&screen,
|
||||
screen.pages.pin(.{ .screen = .{ .y = 0 } }).?,
|
||||
null,
|
||||
null,
|
||||
.{},
|
||||
);
|
||||
var it = shaper.runIterator(.{
|
||||
.grid = testdata.grid,
|
||||
.screen = &screen,
|
||||
.row = screen.pages.pin(.{ .screen = .{ .y = 0 } }).?,
|
||||
});
|
||||
var count: usize = 0;
|
||||
while (try it.next(alloc)) |run| {
|
||||
count += 1;
|
||||
@@ -655,14 +609,11 @@ test "shape variation selector VS16" {
|
||||
|
||||
// Get our run iterator
|
||||
var shaper = &testdata.shaper;
|
||||
var it = shaper.runIterator(
|
||||
testdata.grid,
|
||||
&screen,
|
||||
screen.pages.pin(.{ .screen = .{ .y = 0 } }).?,
|
||||
null,
|
||||
null,
|
||||
.{},
|
||||
);
|
||||
var it = shaper.runIterator(.{
|
||||
.grid = testdata.grid,
|
||||
.screen = &screen,
|
||||
.row = screen.pages.pin(.{ .screen = .{ .y = 0 } }).?,
|
||||
});
|
||||
var count: usize = 0;
|
||||
while (try it.next(alloc)) |run| {
|
||||
count += 1;
|
||||
@@ -690,14 +641,11 @@ test "shape with empty cells in between" {
|
||||
|
||||
// Get our run iterator
|
||||
var shaper = &testdata.shaper;
|
||||
var it = shaper.runIterator(
|
||||
testdata.grid,
|
||||
&screen,
|
||||
screen.pages.pin(.{ .screen = .{ .y = 0 } }).?,
|
||||
null,
|
||||
null,
|
||||
.{},
|
||||
);
|
||||
var it = shaper.runIterator(.{
|
||||
.grid = testdata.grid,
|
||||
.screen = &screen,
|
||||
.row = screen.pages.pin(.{ .screen = .{ .y = 0 } }).?,
|
||||
});
|
||||
var count: usize = 0;
|
||||
while (try it.next(alloc)) |run| {
|
||||
count += 1;
|
||||
@@ -729,14 +677,11 @@ test "shape Chinese characters" {
|
||||
|
||||
// Get our run iterator
|
||||
var shaper = &testdata.shaper;
|
||||
var it = shaper.runIterator(
|
||||
testdata.grid,
|
||||
&screen,
|
||||
screen.pages.pin(.{ .screen = .{ .y = 0 } }).?,
|
||||
null,
|
||||
null,
|
||||
.{},
|
||||
);
|
||||
var it = shaper.runIterator(.{
|
||||
.grid = testdata.grid,
|
||||
.screen = &screen,
|
||||
.row = screen.pages.pin(.{ .screen = .{ .y = 0 } }).?,
|
||||
});
|
||||
var count: usize = 0;
|
||||
while (try it.next(alloc)) |run| {
|
||||
count += 1;
|
||||
@@ -770,14 +715,11 @@ test "shape box glyphs" {
|
||||
|
||||
// Get our run iterator
|
||||
var shaper = &testdata.shaper;
|
||||
var it = shaper.runIterator(
|
||||
testdata.grid,
|
||||
&screen,
|
||||
screen.pages.pin(.{ .screen = .{ .y = 0 } }).?,
|
||||
null,
|
||||
null,
|
||||
.{},
|
||||
);
|
||||
var it = shaper.runIterator(.{
|
||||
.grid = testdata.grid,
|
||||
.screen = &screen,
|
||||
.row = screen.pages.pin(.{ .screen = .{ .y = 0 } }).?,
|
||||
});
|
||||
var count: usize = 0;
|
||||
while (try it.next(alloc)) |run| {
|
||||
count += 1;
|
||||
@@ -808,18 +750,16 @@ test "shape selection boundary" {
|
||||
{
|
||||
// Get our run iterator
|
||||
var shaper = &testdata.shaper;
|
||||
var it = shaper.runIterator(
|
||||
testdata.grid,
|
||||
&screen,
|
||||
screen.pages.pin(.{ .screen = .{ .y = 0 } }).?,
|
||||
terminal.Selection.init(
|
||||
var it = shaper.runIterator(.{
|
||||
.grid = testdata.grid,
|
||||
.screen = &screen,
|
||||
.row = screen.pages.pin(.{ .screen = .{ .y = 0 } }).?,
|
||||
.selection = terminal.Selection.init(
|
||||
screen.pages.pin(.{ .active = .{ .x = 0, .y = 0 } }).?,
|
||||
screen.pages.pin(.{ .active = .{ .x = screen.pages.cols - 1, .y = 0 } }).?,
|
||||
false,
|
||||
),
|
||||
null,
|
||||
.{},
|
||||
);
|
||||
});
|
||||
var count: usize = 0;
|
||||
while (try it.next(alloc)) |run| {
|
||||
count += 1;
|
||||
@@ -832,18 +772,16 @@ test "shape selection boundary" {
|
||||
{
|
||||
// Get our run iterator
|
||||
var shaper = &testdata.shaper;
|
||||
var it = shaper.runIterator(
|
||||
testdata.grid,
|
||||
&screen,
|
||||
screen.pages.pin(.{ .screen = .{ .y = 0 } }).?,
|
||||
terminal.Selection.init(
|
||||
var it = shaper.runIterator(.{
|
||||
.grid = testdata.grid,
|
||||
.screen = &screen,
|
||||
.row = screen.pages.pin(.{ .screen = .{ .y = 0 } }).?,
|
||||
.selection = terminal.Selection.init(
|
||||
screen.pages.pin(.{ .active = .{ .x = 2, .y = 0 } }).?,
|
||||
screen.pages.pin(.{ .active = .{ .x = screen.pages.cols - 1, .y = 0 } }).?,
|
||||
false,
|
||||
),
|
||||
null,
|
||||
.{},
|
||||
);
|
||||
});
|
||||
var count: usize = 0;
|
||||
while (try it.next(alloc)) |run| {
|
||||
count += 1;
|
||||
@@ -856,18 +794,16 @@ test "shape selection boundary" {
|
||||
{
|
||||
// Get our run iterator
|
||||
var shaper = &testdata.shaper;
|
||||
var it = shaper.runIterator(
|
||||
testdata.grid,
|
||||
&screen,
|
||||
screen.pages.pin(.{ .screen = .{ .y = 0 } }).?,
|
||||
terminal.Selection.init(
|
||||
var it = shaper.runIterator(.{
|
||||
.grid = testdata.grid,
|
||||
.screen = &screen,
|
||||
.row = screen.pages.pin(.{ .screen = .{ .y = 0 } }).?,
|
||||
.selection = terminal.Selection.init(
|
||||
screen.pages.pin(.{ .active = .{ .x = 0, .y = 0 } }).?,
|
||||
screen.pages.pin(.{ .active = .{ .x = 3, .y = 0 } }).?,
|
||||
false,
|
||||
),
|
||||
null,
|
||||
.{},
|
||||
);
|
||||
});
|
||||
var count: usize = 0;
|
||||
while (try it.next(alloc)) |run| {
|
||||
count += 1;
|
||||
@@ -880,18 +816,16 @@ test "shape selection boundary" {
|
||||
{
|
||||
// Get our run iterator
|
||||
var shaper = &testdata.shaper;
|
||||
var it = shaper.runIterator(
|
||||
testdata.grid,
|
||||
&screen,
|
||||
screen.pages.pin(.{ .screen = .{ .y = 0 } }).?,
|
||||
terminal.Selection.init(
|
||||
var it = shaper.runIterator(.{
|
||||
.grid = testdata.grid,
|
||||
.screen = &screen,
|
||||
.row = screen.pages.pin(.{ .screen = .{ .y = 0 } }).?,
|
||||
.selection = terminal.Selection.init(
|
||||
screen.pages.pin(.{ .active = .{ .x = 1, .y = 0 } }).?,
|
||||
screen.pages.pin(.{ .active = .{ .x = 3, .y = 0 } }).?,
|
||||
false,
|
||||
),
|
||||
null,
|
||||
.{},
|
||||
);
|
||||
});
|
||||
var count: usize = 0;
|
||||
while (try it.next(alloc)) |run| {
|
||||
count += 1;
|
||||
@@ -904,18 +838,16 @@ test "shape selection boundary" {
|
||||
{
|
||||
// Get our run iterator
|
||||
var shaper = &testdata.shaper;
|
||||
var it = shaper.runIterator(
|
||||
testdata.grid,
|
||||
&screen,
|
||||
screen.pages.pin(.{ .screen = .{ .y = 0 } }).?,
|
||||
terminal.Selection.init(
|
||||
var it = shaper.runIterator(.{
|
||||
.grid = testdata.grid,
|
||||
.screen = &screen,
|
||||
.row = screen.pages.pin(.{ .screen = .{ .y = 0 } }).?,
|
||||
.selection = terminal.Selection.init(
|
||||
screen.pages.pin(.{ .active = .{ .x = 1, .y = 0 } }).?,
|
||||
screen.pages.pin(.{ .active = .{ .x = 1, .y = 0 } }).?,
|
||||
false,
|
||||
),
|
||||
null,
|
||||
.{},
|
||||
);
|
||||
});
|
||||
var count: usize = 0;
|
||||
while (try it.next(alloc)) |run| {
|
||||
count += 1;
|
||||
@@ -941,14 +873,11 @@ test "shape cursor boundary" {
|
||||
{
|
||||
// Get our run iterator
|
||||
var shaper = &testdata.shaper;
|
||||
var it = shaper.runIterator(
|
||||
testdata.grid,
|
||||
&screen,
|
||||
screen.pages.pin(.{ .screen = .{ .y = 0 } }).?,
|
||||
null,
|
||||
null,
|
||||
.{},
|
||||
);
|
||||
var it = shaper.runIterator(.{
|
||||
.grid = testdata.grid,
|
||||
.screen = &screen,
|
||||
.row = screen.pages.pin(.{ .screen = .{ .y = 0 } }).?,
|
||||
});
|
||||
var count: usize = 0;
|
||||
while (try it.next(alloc)) |run| {
|
||||
count += 1;
|
||||
@@ -962,14 +891,12 @@ test "shape cursor boundary" {
|
||||
{
|
||||
// Get our run iterator
|
||||
var shaper = &testdata.shaper;
|
||||
var it = shaper.runIterator(
|
||||
testdata.grid,
|
||||
&screen,
|
||||
screen.pages.pin(.{ .screen = .{ .y = 0 } }).?,
|
||||
null,
|
||||
0,
|
||||
.{ .cursor = true },
|
||||
);
|
||||
var it = shaper.runIterator(.{
|
||||
.grid = testdata.grid,
|
||||
.screen = &screen,
|
||||
.row = screen.pages.pin(.{ .screen = .{ .y = 0 } }).?,
|
||||
.cursor_x = 0,
|
||||
});
|
||||
var count: usize = 0;
|
||||
while (try it.next(alloc)) |run| {
|
||||
count += 1;
|
||||
@@ -981,14 +908,11 @@ test "shape cursor boundary" {
|
||||
{
|
||||
// Get our run iterator
|
||||
var shaper = &testdata.shaper;
|
||||
var it = shaper.runIterator(
|
||||
testdata.grid,
|
||||
&screen,
|
||||
screen.pages.pin(.{ .screen = .{ .y = 0 } }).?,
|
||||
null,
|
||||
0,
|
||||
.{ .cursor = false },
|
||||
);
|
||||
var it = shaper.runIterator(.{
|
||||
.grid = testdata.grid,
|
||||
.screen = &screen,
|
||||
.row = screen.pages.pin(.{ .screen = .{ .y = 0 } }).?,
|
||||
});
|
||||
var count: usize = 0;
|
||||
while (try it.next(alloc)) |run| {
|
||||
count += 1;
|
||||
@@ -1003,14 +927,12 @@ test "shape cursor boundary" {
|
||||
{
|
||||
// Get our run iterator
|
||||
var shaper = &testdata.shaper;
|
||||
var it = shaper.runIterator(
|
||||
testdata.grid,
|
||||
&screen,
|
||||
screen.pages.pin(.{ .screen = .{ .y = 0 } }).?,
|
||||
null,
|
||||
1,
|
||||
.{ .cursor = true },
|
||||
);
|
||||
var it = shaper.runIterator(.{
|
||||
.grid = testdata.grid,
|
||||
.screen = &screen,
|
||||
.row = screen.pages.pin(.{ .screen = .{ .y = 0 } }).?,
|
||||
.cursor_x = 1,
|
||||
});
|
||||
var count: usize = 0;
|
||||
while (try it.next(alloc)) |run| {
|
||||
count += 1;
|
||||
@@ -1022,14 +944,11 @@ test "shape cursor boundary" {
|
||||
{
|
||||
// Get our run iterator
|
||||
var shaper = &testdata.shaper;
|
||||
var it = shaper.runIterator(
|
||||
testdata.grid,
|
||||
&screen,
|
||||
screen.pages.pin(.{ .screen = .{ .y = 0 } }).?,
|
||||
null,
|
||||
1,
|
||||
.{ .cursor = false },
|
||||
);
|
||||
var it = shaper.runIterator(.{
|
||||
.grid = testdata.grid,
|
||||
.screen = &screen,
|
||||
.row = screen.pages.pin(.{ .screen = .{ .y = 0 } }).?,
|
||||
});
|
||||
var count: usize = 0;
|
||||
while (try it.next(alloc)) |run| {
|
||||
count += 1;
|
||||
@@ -1043,14 +962,12 @@ test "shape cursor boundary" {
|
||||
{
|
||||
// Get our run iterator
|
||||
var shaper = &testdata.shaper;
|
||||
var it = shaper.runIterator(
|
||||
testdata.grid,
|
||||
&screen,
|
||||
screen.pages.pin(.{ .screen = .{ .y = 0 } }).?,
|
||||
null,
|
||||
9,
|
||||
.{ .cursor = true },
|
||||
);
|
||||
var it = shaper.runIterator(.{
|
||||
.grid = testdata.grid,
|
||||
.screen = &screen,
|
||||
.row = screen.pages.pin(.{ .screen = .{ .y = 0 } }).?,
|
||||
.cursor_x = 9,
|
||||
});
|
||||
var count: usize = 0;
|
||||
while (try it.next(alloc)) |run| {
|
||||
count += 1;
|
||||
@@ -1062,14 +979,11 @@ test "shape cursor boundary" {
|
||||
{
|
||||
// Get our run iterator
|
||||
var shaper = &testdata.shaper;
|
||||
var it = shaper.runIterator(
|
||||
testdata.grid,
|
||||
&screen,
|
||||
screen.pages.pin(.{ .screen = .{ .y = 0 } }).?,
|
||||
null,
|
||||
9,
|
||||
.{ .cursor = false },
|
||||
);
|
||||
var it = shaper.runIterator(.{
|
||||
.grid = testdata.grid,
|
||||
.screen = &screen,
|
||||
.row = screen.pages.pin(.{ .screen = .{ .y = 0 } }).?,
|
||||
});
|
||||
var count: usize = 0;
|
||||
while (try it.next(alloc)) |run| {
|
||||
count += 1;
|
||||
@@ -1096,14 +1010,11 @@ test "shape cursor boundary and colored emoji" {
|
||||
{
|
||||
// Get our run iterator
|
||||
var shaper = &testdata.shaper;
|
||||
var it = shaper.runIterator(
|
||||
testdata.grid,
|
||||
&screen,
|
||||
screen.pages.pin(.{ .screen = .{ .y = 0 } }).?,
|
||||
null,
|
||||
null,
|
||||
.{},
|
||||
);
|
||||
var it = shaper.runIterator(.{
|
||||
.grid = testdata.grid,
|
||||
.screen = &screen,
|
||||
.row = screen.pages.pin(.{ .screen = .{ .y = 0 } }).?,
|
||||
});
|
||||
var count: usize = 0;
|
||||
while (try it.next(alloc)) |run| {
|
||||
count += 1;
|
||||
@@ -1116,14 +1027,12 @@ test "shape cursor boundary and colored emoji" {
|
||||
{
|
||||
// Get our run iterator
|
||||
var shaper = &testdata.shaper;
|
||||
var it = shaper.runIterator(
|
||||
testdata.grid,
|
||||
&screen,
|
||||
screen.pages.pin(.{ .screen = .{ .y = 0 } }).?,
|
||||
null,
|
||||
0,
|
||||
.{ .cursor = true },
|
||||
);
|
||||
var it = shaper.runIterator(.{
|
||||
.grid = testdata.grid,
|
||||
.screen = &screen,
|
||||
.row = screen.pages.pin(.{ .screen = .{ .y = 0 } }).?,
|
||||
.cursor_x = 0,
|
||||
});
|
||||
var count: usize = 0;
|
||||
while (try it.next(alloc)) |run| {
|
||||
count += 1;
|
||||
@@ -1134,14 +1043,11 @@ test "shape cursor boundary and colored emoji" {
|
||||
{
|
||||
// Get our run iterator
|
||||
var shaper = &testdata.shaper;
|
||||
var it = shaper.runIterator(
|
||||
testdata.grid,
|
||||
&screen,
|
||||
screen.pages.pin(.{ .screen = .{ .y = 0 } }).?,
|
||||
null,
|
||||
0,
|
||||
.{ .cursor = false },
|
||||
);
|
||||
var it = shaper.runIterator(.{
|
||||
.grid = testdata.grid,
|
||||
.screen = &screen,
|
||||
.row = screen.pages.pin(.{ .screen = .{ .y = 0 } }).?,
|
||||
});
|
||||
var count: usize = 0;
|
||||
while (try it.next(alloc)) |run| {
|
||||
count += 1;
|
||||
@@ -1152,14 +1058,12 @@ test "shape cursor boundary and colored emoji" {
|
||||
{
|
||||
// Get our run iterator
|
||||
var shaper = &testdata.shaper;
|
||||
var it = shaper.runIterator(
|
||||
testdata.grid,
|
||||
&screen,
|
||||
screen.pages.pin(.{ .screen = .{ .y = 0 } }).?,
|
||||
null,
|
||||
1,
|
||||
.{ .cursor = true },
|
||||
);
|
||||
var it = shaper.runIterator(.{
|
||||
.grid = testdata.grid,
|
||||
.screen = &screen,
|
||||
.row = screen.pages.pin(.{ .screen = .{ .y = 0 } }).?,
|
||||
.cursor_x = 1,
|
||||
});
|
||||
var count: usize = 0;
|
||||
while (try it.next(alloc)) |run| {
|
||||
count += 1;
|
||||
@@ -1170,14 +1074,11 @@ test "shape cursor boundary and colored emoji" {
|
||||
{
|
||||
// Get our run iterator
|
||||
var shaper = &testdata.shaper;
|
||||
var it = shaper.runIterator(
|
||||
testdata.grid,
|
||||
&screen,
|
||||
screen.pages.pin(.{ .screen = .{ .y = 0 } }).?,
|
||||
null,
|
||||
1,
|
||||
.{ .cursor = false },
|
||||
);
|
||||
var it = shaper.runIterator(.{
|
||||
.grid = testdata.grid,
|
||||
.screen = &screen,
|
||||
.row = screen.pages.pin(.{ .screen = .{ .y = 0 } }).?,
|
||||
});
|
||||
var count: usize = 0;
|
||||
while (try it.next(alloc)) |run| {
|
||||
count += 1;
|
||||
@@ -1201,14 +1102,11 @@ test "shape cell attribute change" {
|
||||
try screen.testWriteString(">=");
|
||||
|
||||
var shaper = &testdata.shaper;
|
||||
var it = shaper.runIterator(
|
||||
testdata.grid,
|
||||
&screen,
|
||||
screen.pages.pin(.{ .screen = .{ .y = 0 } }).?,
|
||||
null,
|
||||
null,
|
||||
.{},
|
||||
);
|
||||
var it = shaper.runIterator(.{
|
||||
.grid = testdata.grid,
|
||||
.screen = &screen,
|
||||
.row = screen.pages.pin(.{ .screen = .{ .y = 0 } }).?,
|
||||
});
|
||||
var count: usize = 0;
|
||||
while (try it.next(alloc)) |run| {
|
||||
count += 1;
|
||||
@@ -1226,14 +1124,11 @@ test "shape cell attribute change" {
|
||||
try screen.testWriteString("=");
|
||||
|
||||
var shaper = &testdata.shaper;
|
||||
var it = shaper.runIterator(
|
||||
testdata.grid,
|
||||
&screen,
|
||||
screen.pages.pin(.{ .screen = .{ .y = 0 } }).?,
|
||||
null,
|
||||
null,
|
||||
.{},
|
||||
);
|
||||
var it = shaper.runIterator(.{
|
||||
.grid = testdata.grid,
|
||||
.screen = &screen,
|
||||
.row = screen.pages.pin(.{ .screen = .{ .y = 0 } }).?,
|
||||
});
|
||||
var count: usize = 0;
|
||||
while (try it.next(alloc)) |run| {
|
||||
count += 1;
|
||||
@@ -1252,14 +1147,11 @@ test "shape cell attribute change" {
|
||||
try screen.testWriteString("=");
|
||||
|
||||
var shaper = &testdata.shaper;
|
||||
var it = shaper.runIterator(
|
||||
testdata.grid,
|
||||
&screen,
|
||||
screen.pages.pin(.{ .screen = .{ .y = 0 } }).?,
|
||||
null,
|
||||
null,
|
||||
.{},
|
||||
);
|
||||
var it = shaper.runIterator(.{
|
||||
.grid = testdata.grid,
|
||||
.screen = &screen,
|
||||
.row = screen.pages.pin(.{ .screen = .{ .y = 0 } }).?,
|
||||
});
|
||||
var count: usize = 0;
|
||||
while (try it.next(alloc)) |run| {
|
||||
count += 1;
|
||||
@@ -1278,14 +1170,11 @@ test "shape cell attribute change" {
|
||||
try screen.testWriteString("=");
|
||||
|
||||
var shaper = &testdata.shaper;
|
||||
var it = shaper.runIterator(
|
||||
testdata.grid,
|
||||
&screen,
|
||||
screen.pages.pin(.{ .screen = .{ .y = 0 } }).?,
|
||||
null,
|
||||
null,
|
||||
.{},
|
||||
);
|
||||
var it = shaper.runIterator(.{
|
||||
.grid = testdata.grid,
|
||||
.screen = &screen,
|
||||
.row = screen.pages.pin(.{ .screen = .{ .y = 0 } }).?,
|
||||
});
|
||||
var count: usize = 0;
|
||||
while (try it.next(alloc)) |run| {
|
||||
count += 1;
|
||||
@@ -1303,14 +1192,11 @@ test "shape cell attribute change" {
|
||||
try screen.testWriteString("=");
|
||||
|
||||
var shaper = &testdata.shaper;
|
||||
var it = shaper.runIterator(
|
||||
testdata.grid,
|
||||
&screen,
|
||||
screen.pages.pin(.{ .screen = .{ .y = 0 } }).?,
|
||||
null,
|
||||
null,
|
||||
.{},
|
||||
);
|
||||
var it = shaper.runIterator(.{
|
||||
.grid = testdata.grid,
|
||||
.screen = &screen,
|
||||
.row = screen.pages.pin(.{ .screen = .{ .y = 0 } }).?,
|
||||
});
|
||||
var count: usize = 0;
|
||||
while (try it.next(alloc)) |run| {
|
||||
count += 1;
|
||||
|
@@ -3,7 +3,6 @@ const assert = std.debug.assert;
|
||||
const Allocator = std.mem.Allocator;
|
||||
const trace = @import("tracy").trace;
|
||||
const font = @import("../main.zig");
|
||||
const config = @import("../../config.zig");
|
||||
const Face = font.Face;
|
||||
const Collection = font.Collection;
|
||||
const DeferredFace = font.DeferredFace;
|
||||
@@ -71,21 +70,11 @@ pub const Shaper = struct {
|
||||
|
||||
pub fn runIterator(
|
||||
self: *Shaper,
|
||||
grid: *SharedGrid,
|
||||
screen: *const terminal.Screen,
|
||||
row: terminal.Pin,
|
||||
selection: ?terminal.Selection,
|
||||
cursor_x: ?usize,
|
||||
break_config: config.FontShapingBreak,
|
||||
opts: font.shape.RunOptions,
|
||||
) font.shape.RunIterator {
|
||||
return .{
|
||||
.hooks = .{ .shaper = self },
|
||||
.grid = grid,
|
||||
.screen = screen,
|
||||
.row = row,
|
||||
.selection = selection,
|
||||
.cursor_x = cursor_x,
|
||||
.break_config = break_config,
|
||||
.opts = opts,
|
||||
};
|
||||
}
|
||||
|
||||
|
@@ -6,8 +6,6 @@ const shape = @import("../shape.zig");
|
||||
const terminal = @import("../../terminal/main.zig");
|
||||
const autoHash = std.hash.autoHash;
|
||||
const Hasher = std.hash.Wyhash;
|
||||
const configpkg = @import("../../config.zig");
|
||||
const Config = configpkg.Config;
|
||||
|
||||
/// A single text run. A text run is only valid for one Shaper instance and
|
||||
/// until the next run is created. A text run never goes across multiple
|
||||
@@ -37,16 +35,11 @@ pub const TextRun = struct {
|
||||
/// RunIterator is an iterator that yields text runs.
|
||||
pub const RunIterator = struct {
|
||||
hooks: font.Shaper.RunIteratorHook,
|
||||
grid: *font.SharedGrid,
|
||||
screen: *const terminal.Screen,
|
||||
row: terminal.Pin,
|
||||
selection: ?terminal.Selection = null,
|
||||
cursor_x: ?usize = null,
|
||||
break_config: configpkg.FontShapingBreak,
|
||||
opts: shape.RunOptions,
|
||||
i: usize = 0,
|
||||
|
||||
pub fn next(self: *RunIterator, alloc: Allocator) !?TextRun {
|
||||
const cells = self.row.cells(.all);
|
||||
const cells = self.opts.row.cells(.all);
|
||||
|
||||
// Trim the right side of a row that might be empty
|
||||
const max: usize = max: {
|
||||
@@ -61,7 +54,7 @@ pub const RunIterator = struct {
|
||||
// Invisible cells don't have any glyphs rendered,
|
||||
// so we explicitly skip them in the shaping process.
|
||||
while (self.i < max and
|
||||
self.row.style(&cells[self.i]).flags.invisible)
|
||||
self.opts.row.style(&cells[self.i]).flags.invisible)
|
||||
{
|
||||
self.i += 1;
|
||||
}
|
||||
@@ -79,7 +72,7 @@ pub const RunIterator = struct {
|
||||
var hasher = Hasher.init(0);
|
||||
|
||||
// Let's get our style that we'll expect for the run.
|
||||
const style = self.row.style(&cells[self.i]);
|
||||
const style = self.opts.row.style(&cells[self.i]);
|
||||
|
||||
// Go through cell by cell and accumulate while we build our run.
|
||||
var j: usize = self.i;
|
||||
@@ -89,9 +82,9 @@ pub const RunIterator = struct {
|
||||
|
||||
// If we have a selection and we're at a boundary point, then
|
||||
// we break the run here.
|
||||
if (self.selection) |unordered_sel| {
|
||||
if (self.opts.selection) |unordered_sel| {
|
||||
if (j > self.i) {
|
||||
const sel = unordered_sel.ordered(self.screen, .forward);
|
||||
const sel = unordered_sel.ordered(self.opts.screen, .forward);
|
||||
const start_x = sel.start().x;
|
||||
const end_x = sel.end().x;
|
||||
|
||||
@@ -145,7 +138,7 @@ pub const RunIterator = struct {
|
||||
// The style is different. We allow differing background
|
||||
// styles but any other change results in a new run.
|
||||
const c1 = comparableStyle(style);
|
||||
const c2 = comparableStyle(self.row.style(&cells[j]));
|
||||
const c2 = comparableStyle(self.opts.row.style(&cells[j]));
|
||||
if (!c1.eql(c2)) break;
|
||||
}
|
||||
|
||||
@@ -165,7 +158,7 @@ pub const RunIterator = struct {
|
||||
const presentation: ?font.Presentation = if (cell.hasGrapheme()) p: {
|
||||
// We only check the FIRST codepoint because I believe the
|
||||
// presentation format must be directly adjacent to the codepoint.
|
||||
const cps = self.row.grapheme(cell) orelse break :p null;
|
||||
const cps = self.opts.row.grapheme(cell) orelse break :p null;
|
||||
assert(cps.len > 0);
|
||||
if (cps[0] == 0xFE0E) break :p .text;
|
||||
if (cps[0] == 0xFE0F) break :p .emoji;
|
||||
@@ -178,38 +171,36 @@ pub const RunIterator = struct {
|
||||
break :emoji null;
|
||||
};
|
||||
|
||||
if (self.break_config.cursor) {
|
||||
// If our cursor is on this line then we break the run around the
|
||||
// cursor. This means that any row with a cursor has at least
|
||||
// three breaks: before, exactly the cursor, and after.
|
||||
//
|
||||
// We do not break a cell that is exactly the grapheme. If there
|
||||
// are cells following that contain joiners, we allow those to
|
||||
// break. This creates an effect where hovering over an emoji
|
||||
// such as a skin-tone emoji is fine, but hovering over the
|
||||
// joiners will show the joiners allowing you to modify the
|
||||
// emoji.
|
||||
if (!cell.hasGrapheme()) {
|
||||
if (self.cursor_x) |cursor_x| {
|
||||
// Exactly: self.i is the cursor and we iterated once. This
|
||||
// means that we started exactly at the cursor and did at
|
||||
// exactly one iteration. Why exactly one? Because we may
|
||||
// start at our cursor but do many if our cursor is exactly
|
||||
// on an emoji.
|
||||
if (self.i == cursor_x and j == self.i + 1) break;
|
||||
// If our cursor is on this line then we break the run around the
|
||||
// cursor. This means that any row with a cursor has at least
|
||||
// three breaks: before, exactly the cursor, and after.
|
||||
//
|
||||
// We do not break a cell that is exactly the grapheme. If there
|
||||
// are cells following that contain joiners, we allow those to
|
||||
// break. This creates an effect where hovering over an emoji
|
||||
// such as a skin-tone emoji is fine, but hovering over the
|
||||
// joiners will show the joiners allowing you to modify the
|
||||
// emoji.
|
||||
if (!cell.hasGrapheme()) {
|
||||
if (self.opts.cursor_x) |cursor_x| {
|
||||
// Exactly: self.i is the cursor and we iterated once. This
|
||||
// means that we started exactly at the cursor and did at
|
||||
// exactly one iteration. Why exactly one? Because we may
|
||||
// start at our cursor but do many if our cursor is exactly
|
||||
// on an emoji.
|
||||
if (self.i == cursor_x and j == self.i + 1) break;
|
||||
|
||||
// Before: up to and not including the cursor. This means
|
||||
// that we started before the cursor (self.i < cursor_x)
|
||||
// and j is now at the cursor meaning we haven't yet processed
|
||||
// the cursor.
|
||||
if (self.i < cursor_x and j == cursor_x) {
|
||||
assert(j > 0);
|
||||
break;
|
||||
}
|
||||
|
||||
// After: after the cursor. We don't need to do anything
|
||||
// special, we just let the run complete.
|
||||
// Before: up to and not including the cursor. This means
|
||||
// that we started before the cursor (self.i < cursor_x)
|
||||
// and j is now at the cursor meaning we haven't yet processed
|
||||
// the cursor.
|
||||
if (self.i < cursor_x and j == cursor_x) {
|
||||
assert(j > 0);
|
||||
break;
|
||||
}
|
||||
|
||||
// After: after the cursor. We don't need to do anything
|
||||
// special, we just let the run complete.
|
||||
}
|
||||
}
|
||||
|
||||
@@ -232,7 +223,7 @@ pub const RunIterator = struct {
|
||||
|
||||
// Otherwise we need a fallback character. Prefer the
|
||||
// official replacement character.
|
||||
if (try self.grid.getIndex(
|
||||
if (try self.opts.grid.getIndex(
|
||||
alloc,
|
||||
0xFFFD, // replacement char
|
||||
font_style,
|
||||
@@ -240,7 +231,7 @@ pub const RunIterator = struct {
|
||||
)) |idx| break :font_info .{ .idx = idx, .fallback = 0xFFFD };
|
||||
|
||||
// Fallback to space
|
||||
if (try self.grid.getIndex(
|
||||
if (try self.opts.grid.getIndex(
|
||||
alloc,
|
||||
' ',
|
||||
font_style,
|
||||
@@ -278,7 +269,7 @@ pub const RunIterator = struct {
|
||||
@intCast(cluster),
|
||||
);
|
||||
if (cell.hasGrapheme()) {
|
||||
const cps = self.row.grapheme(cell).?;
|
||||
const cps = self.opts.row.grapheme(cell).?;
|
||||
for (cps) |cp| {
|
||||
// Do not send presentation modifiers
|
||||
if (cp == 0xFE0E or cp == 0xFE0F) continue;
|
||||
@@ -303,7 +294,7 @@ pub const RunIterator = struct {
|
||||
.hash = hasher.final(),
|
||||
.offset = @intCast(self.i),
|
||||
.cells = @intCast(j - self.i),
|
||||
.grid = self.grid,
|
||||
.grid = self.opts.grid,
|
||||
.font_index = current_font,
|
||||
};
|
||||
}
|
||||
@@ -331,7 +322,7 @@ pub const RunIterator = struct {
|
||||
cell.codepoint() == 0 or
|
||||
cell.codepoint() == terminal.kitty.graphics.unicode.placeholder)
|
||||
{
|
||||
return try self.grid.getIndex(
|
||||
return try self.opts.grid.getIndex(
|
||||
alloc,
|
||||
' ',
|
||||
style,
|
||||
@@ -341,7 +332,7 @@ pub const RunIterator = struct {
|
||||
|
||||
// Get the font index for the primary codepoint.
|
||||
const primary_cp: u32 = cell.codepoint();
|
||||
const primary = try self.grid.getIndex(
|
||||
const primary = try self.opts.grid.getIndex(
|
||||
alloc,
|
||||
primary_cp,
|
||||
style,
|
||||
@@ -354,7 +345,7 @@ pub const RunIterator = struct {
|
||||
|
||||
// If this is a grapheme, we need to find a font that supports
|
||||
// all of the codepoints in the grapheme.
|
||||
const cps = self.row.grapheme(cell) orelse return primary;
|
||||
const cps = self.opts.row.grapheme(cell) orelse return primary;
|
||||
var candidates = try std.ArrayList(font.Collection.Index).initCapacity(alloc, cps.len + 1);
|
||||
defer candidates.deinit();
|
||||
candidates.appendAssumeCapacity(primary);
|
||||
@@ -370,7 +361,7 @@ pub const RunIterator = struct {
|
||||
// to support the base presentation, since it is common for emoji
|
||||
// fonts to support the base emoji with emoji presentation but not
|
||||
// certain ZWJ-combined characters like the male and female signs.
|
||||
const idx = try self.grid.getIndex(
|
||||
const idx = try self.opts.grid.getIndex(
|
||||
alloc,
|
||||
cp,
|
||||
style,
|
||||
@@ -381,11 +372,11 @@ pub const RunIterator = struct {
|
||||
|
||||
// We need to find a candidate that has ALL of our codepoints
|
||||
for (candidates.items) |idx| {
|
||||
if (!self.grid.hasCodepoint(idx, primary_cp, presentation)) continue;
|
||||
if (!self.opts.grid.hasCodepoint(idx, primary_cp, presentation)) continue;
|
||||
for (cps) |cp| {
|
||||
// Ignore Emoji ZWJs
|
||||
if (cp == 0xFE0E or cp == 0xFE0F or cp == 0x200D) continue;
|
||||
if (!self.grid.hasCodepoint(idx, cp, null)) break;
|
||||
if (!self.opts.grid.hasCodepoint(idx, cp, null)) break;
|
||||
} else {
|
||||
// If the while completed, then we have a candidate that
|
||||
// supports all of our codepoints.
|
||||
|
@@ -4,7 +4,6 @@ const Allocator = std.mem.Allocator;
|
||||
const ziglyph = @import("ziglyph");
|
||||
const font = @import("../main.zig");
|
||||
const terminal = @import("../../terminal/main.zig");
|
||||
const config = @import("../../config.zig");
|
||||
|
||||
const log = std.log.scoped(.font_shaper);
|
||||
|
||||
@@ -62,19 +61,11 @@ pub const Shaper = struct {
|
||||
/// for a Shaper struct since they share state.
|
||||
pub fn runIterator(
|
||||
self: *Shaper,
|
||||
group: *font.GroupCache,
|
||||
row: terminal.Screen.Row,
|
||||
selection: ?terminal.Selection,
|
||||
cursor_x: ?usize,
|
||||
break_config: config.FontShapingBreak,
|
||||
opts: font.shape.RunOptions,
|
||||
) font.shape.RunIterator {
|
||||
return .{
|
||||
.hooks = .{ .shaper = self },
|
||||
.group = group,
|
||||
.row = row,
|
||||
.selection = selection,
|
||||
.cursor_x = cursor_x,
|
||||
.break_config = break_config,
|
||||
.opts = opts,
|
||||
};
|
||||
}
|
||||
|
||||
|
@@ -513,6 +513,7 @@ pub fn Renderer(comptime GraphicsAPI: type) type {
|
||||
font_thicken_strength: u8,
|
||||
font_features: std.ArrayListUnmanaged([:0]const u8),
|
||||
font_styles: font.CodepointResolver.StyleStatus,
|
||||
font_shaping_break: configpkg.FontShapingBreak,
|
||||
cursor_color: ?terminal.color.RGB,
|
||||
cursor_invert: bool,
|
||||
cursor_opacity: f64,
|
||||
@@ -578,6 +579,7 @@ pub fn Renderer(comptime GraphicsAPI: type) type {
|
||||
.font_thicken_strength = config.@"font-thicken-strength",
|
||||
.font_features = font_features.list,
|
||||
.font_styles = font_styles,
|
||||
.font_shaping_break = config.@"font-shaping-break",
|
||||
|
||||
.cursor_color = if (!cursor_invert and config.@"cursor-color" != null)
|
||||
config.@"cursor-color".?.toTerminalRGB()
|
||||
@@ -2467,13 +2469,15 @@ pub fn Renderer(comptime GraphicsAPI: type) type {
|
||||
}
|
||||
|
||||
// Iterator of runs for shaping.
|
||||
var run_iter = self.font_shaper.runIterator(
|
||||
self.font_grid,
|
||||
screen,
|
||||
row,
|
||||
row_selection,
|
||||
if (shape_cursor) screen.cursor.x else null,
|
||||
);
|
||||
var run_iter_opts: font.shape.RunOptions = .{
|
||||
.grid = self.font_grid,
|
||||
.screen = screen,
|
||||
.row = row,
|
||||
.selection = row_selection,
|
||||
.cursor_x = if (shape_cursor) screen.cursor.x else null,
|
||||
};
|
||||
run_iter_opts.applyBreakConfig(self.config.font_shaping_break);
|
||||
var run_iter = self.font_shaper.runIterator(run_iter_opts);
|
||||
var shaper_run: ?font.shape.TextRun = try run_iter.next(self.alloc);
|
||||
var shaper_cells: ?[]const font.shape.Cell = null;
|
||||
var shaper_cells_i: usize = 0;
|
||||
|
Reference in New Issue
Block a user