terminal: Coordinate uses CellCountInt

This commit is contained in:
Mitchell Hashimoto
2024-04-26 20:52:08 -07:00
parent 2b67eaa18d
commit 3f16234f72
9 changed files with 111 additions and 53 deletions

View File

@ -1908,7 +1908,7 @@ fn rebuildCells2(
// font shaping by row. In the future, we will also do dirty tracking // font shaping by row. In the future, we will also do dirty tracking
// by row. // by row.
var row_it = screen.pages.rowIterator(.right_down, .{ .viewport = .{} }, null); var row_it = screen.pages.rowIterator(.right_down, .{ .viewport = .{} }, null);
var y: usize = 0; var y: terminal.size.CellCountInt = 0;
while (row_it.next()) |row| { while (row_it.next()) |row| {
defer y += 1; defer y += 1;

View File

@ -232,7 +232,10 @@ test Contents {
// Assert that get returns null for everything. // Assert that get returns null for everything.
for (0..rows) |y| { for (0..rows) |y| {
for (0..cols) |x| { for (0..cols) |x| {
try testing.expect(c.get(.bg, .{ .x = x, .y = y }) == null); try testing.expect(c.get(.bg, .{
.x = @intCast(x),
.y = @intCast(y),
}) == null);
} }
} }
@ -250,7 +253,10 @@ test Contents {
c.clear(1); c.clear(1);
for (0..rows) |y| { for (0..rows) |y| {
for (0..cols) |x| { for (0..cols) |x| {
try testing.expect(c.get(.bg, .{ .x = x, .y = y }) == null); try testing.expect(c.get(.bg, .{
.x = @intCast(x),
.y = @intCast(y),
}) == null);
} }
} }
} }

View File

@ -287,12 +287,12 @@ fn initPostPipeline(
/// This is a single parameter for the terminal cell shader. /// This is a single parameter for the terminal cell shader.
pub const CellText = extern struct { pub const CellText = extern struct {
mode: Mode, mode: Mode,
grid_pos: [2]u16,
glyph_pos: [2]u32 = .{ 0, 0 }, glyph_pos: [2]u32 = .{ 0, 0 },
glyph_size: [2]u32 = .{ 0, 0 }, glyph_size: [2]u32 = .{ 0, 0 },
glyph_offset: [2]i32 = .{ 0, 0 }, glyph_offset: [2]i32 = .{ 0, 0 },
color: [4]u8, color: [4]u8,
bg_color: [4]u8, bg_color: [4]u8,
grid_pos: [2]u16,
cell_width: u8, cell_width: u8,
pub const Mode = enum(u8) { pub const Mode = enum(u8) {

View File

@ -1421,7 +1421,7 @@ fn resizeWithoutReflowGrowCols(
// Keeps track of all our copied rows. Assertions at the end is that // Keeps track of all our copied rows. Assertions at the end is that
// we copied exactly our page size. // we copied exactly our page size.
var copied: usize = 0; var copied: size.CellCountInt = 0;
// This function has an unfortunate side effect in that it causes memory // This function has an unfortunate side effect in that it causes memory
// fragmentation on rows if the columns are increasing in a way that // fragmentation on rows if the columns are increasing in a way that
@ -2545,7 +2545,7 @@ pub fn cellIterator(
pub const RowIterator = struct { pub const RowIterator = struct {
page_it: PageIterator, page_it: PageIterator,
chunk: ?PageIterator.Chunk = null, chunk: ?PageIterator.Chunk = null,
offset: usize = 0, offset: size.CellCountInt = 0,
pub fn next(self: *RowIterator) ?Pin { pub fn next(self: *RowIterator) ?Pin {
const chunk = self.chunk orelse return null; const chunk = self.chunk orelse return null;
@ -2767,8 +2767,8 @@ pub const PageIterator = struct {
pub const Chunk = struct { pub const Chunk = struct {
page: *List.Node, page: *List.Node,
start: usize, start: size.CellCountInt,
end: usize, end: size.CellCountInt,
pub fn rows(self: Chunk) []Row { pub fn rows(self: Chunk) []Row {
const rows_ptr = self.page.data.rows.ptr(self.page.data.memory); const rows_ptr = self.page.data.rows.ptr(self.page.data.memory);
@ -2944,8 +2944,8 @@ fn growRows(self: *PageList, n: usize) !void {
/// should limit the number of active pins as much as possible. /// should limit the number of active pins as much as possible.
pub const Pin = struct { pub const Pin = struct {
page: *List.Node, page: *List.Node,
y: usize = 0, y: size.CellCountInt = 0,
x: usize = 0, x: size.CellCountInt = 0,
pub fn rowAndCell(self: Pin) struct { pub fn rowAndCell(self: Pin) struct {
row: *pagepkg.Row, row: *pagepkg.Row,
@ -3104,7 +3104,7 @@ pub const Pin = struct {
pub fn left(self: Pin, n: usize) Pin { pub fn left(self: Pin, n: usize) Pin {
assert(n <= self.x); assert(n <= self.x);
var result = self; var result = self;
result.x -= n; result.x -= std.math.cast(size.CellCountInt, n) orelse result.x;
return result; return result;
} }
@ -3112,7 +3112,8 @@ pub const Pin = struct {
pub fn right(self: Pin, n: usize) Pin { pub fn right(self: Pin, n: usize) Pin {
assert(self.x + n < self.page.data.size.cols); assert(self.x + n < self.page.data.size.cols);
var result = self; var result = self;
result.x += n; result.x +|= std.math.cast(size.CellCountInt, n) orelse
std.math.maxInt(size.CellCountInt);
return result; return result;
} }
@ -3147,7 +3148,8 @@ pub const Pin = struct {
const rows = self.page.data.size.rows - (self.y + 1); const rows = self.page.data.size.rows - (self.y + 1);
if (n <= rows) return .{ .offset = .{ if (n <= rows) return .{ .offset = .{
.page = self.page, .page = self.page,
.y = n + self.y, .y = std.math.cast(size.CellCountInt, self.y + n) orelse
std.math.maxInt(size.CellCountInt),
.x = self.x, .x = self.x,
} }; } };
@ -3165,7 +3167,8 @@ pub const Pin = struct {
} }; } };
if (n_left <= page.data.size.rows) return .{ .offset = .{ if (n_left <= page.data.size.rows) return .{ .offset = .{
.page = page, .page = page,
.y = n_left - 1, .y = std.math.cast(size.CellCountInt, n_left - 1) orelse
std.math.maxInt(size.CellCountInt),
.x = self.x, .x = self.x,
} }; } };
n_left -= page.data.size.rows; n_left -= page.data.size.rows;
@ -3184,7 +3187,8 @@ pub const Pin = struct {
// Index fits within this page // Index fits within this page
if (n <= self.y) return .{ .offset = .{ if (n <= self.y) return .{ .offset = .{
.page = self.page, .page = self.page,
.y = self.y - n, .y = std.math.cast(size.CellCountInt, self.y - n) orelse
std.math.maxInt(size.CellCountInt),
.x = self.x, .x = self.x,
} }; } };
@ -3198,7 +3202,8 @@ pub const Pin = struct {
} }; } };
if (n_left <= page.data.size.rows) return .{ .offset = .{ if (n_left <= page.data.size.rows) return .{ .offset = .{
.page = page, .page = page,
.y = page.data.size.rows - n_left, .y = std.math.cast(size.CellCountInt, page.data.size.rows - n_left) orelse
std.math.maxInt(size.CellCountInt),
.x = self.x, .x = self.x,
} }; } };
n_left -= page.data.size.rows; n_left -= page.data.size.rows;
@ -3210,8 +3215,8 @@ const Cell = struct {
page: *List.Node, page: *List.Node,
row: *pagepkg.Row, row: *pagepkg.Row,
cell: *pagepkg.Cell, cell: *pagepkg.Cell,
row_idx: usize, row_idx: size.CellCountInt,
col_idx: usize, col_idx: size.CellCountInt,
/// Get the cell style. /// Get the cell style.
/// ///
@ -3231,7 +3236,7 @@ const Cell = struct {
/// this file then consider a different approach and ask yourself very /// this file then consider a different approach and ask yourself very
/// carefully if you really need this. /// carefully if you really need this.
pub fn screenPoint(self: Cell) point.Point { pub fn screenPoint(self: Cell) point.Point {
var y: usize = self.row_idx; var y: size.CellCountInt = self.row_idx;
var page = self.page; var page = self.page;
while (page.prev) |prev| { while (page.prev) |prev| {
y += prev.data.size.rows; y += prev.data.size.rows;
@ -3402,7 +3407,7 @@ test "PageList pointFromPin traverse pages" {
try testing.expectEqual(point.Point{ try testing.expectEqual(point.Point{
.screen = .{ .screen = .{
.y = expected_y, .y = @intCast(expected_y),
.x = 2, .x = 2,
}, },
}, s.pointFromPin(.screen, .{ }, s.pointFromPin(.screen, .{
@ -5629,7 +5634,7 @@ test "PageList resize (no reflow) more rows adds blank rows if cursor at bottom"
// Go through our active, we should get only 3,4,5 // Go through our active, we should get only 3,4,5
for (0..3) |y| { for (0..3) |y| {
const get = s.getCell(.{ .active = .{ .y = y } }).?; const get = s.getCell(.{ .active = .{ .y = @intCast(y) } }).?;
const expected: u21 = @intCast(y + 2); const expected: u21 = @intCast(y + 2);
try testing.expectEqual(expected, get.cell.content.codepoint); try testing.expectEqual(expected, get.cell.content.codepoint);
} }
@ -6557,7 +6562,7 @@ test "PageList resize reflow less cols no wrapped rows" {
while (it.next()) |offset| { while (it.next()) |offset| {
for (0..4) |x| { for (0..4) |x| {
var offset_copy = offset; var offset_copy = offset;
offset_copy.x = x; offset_copy.x = @intCast(x);
const rac = offset_copy.rowAndCell(); const rac = offset_copy.rowAndCell();
const cells = offset.page.data.getCells(rac.row); const cells = offset.page.data.getCells(rac.row);
try testing.expectEqual(@as(usize, 5), cells.len); try testing.expectEqual(@as(usize, 5), cells.len);
@ -7247,7 +7252,7 @@ test "PageList resize reflow less cols copy style" {
while (it.next()) |offset| { while (it.next()) |offset| {
for (0..s.cols - 1) |x| { for (0..s.cols - 1) |x| {
var offset_copy = offset; var offset_copy = offset;
offset_copy.x = x; offset_copy.x = @intCast(x);
const rac = offset_copy.rowAndCell(); const rac = offset_copy.rowAndCell();
const style_id = rac.cell.style_id; const style_id = rac.cell.style_id;
try testing.expect(style_id != 0); try testing.expect(style_id != 0);

View File

@ -1412,8 +1412,8 @@ pub fn selectionString(self: *Screen, alloc: Allocator, opts: SelectionString) !
if (mapbuilder) |*b| { if (mapbuilder) |*b| {
for (0..encode_len) |_| try b.append(.{ for (0..encode_len) |_| try b.append(.{
.page = chunk.page, .page = chunk.page,
.y = y, .y = @intCast(y),
.x = x, .x = @intCast(x),
}); });
} }
} }
@ -1425,8 +1425,8 @@ pub fn selectionString(self: *Screen, alloc: Allocator, opts: SelectionString) !
if (mapbuilder) |*b| { if (mapbuilder) |*b| {
for (0..encode_len) |_| try b.append(.{ for (0..encode_len) |_| try b.append(.{
.page = chunk.page, .page = chunk.page,
.y = y, .y = @intCast(y),
.x = x, .x = @intCast(x),
}); });
} }
} }
@ -1441,7 +1441,7 @@ pub fn selectionString(self: *Screen, alloc: Allocator, opts: SelectionString) !
try strbuilder.append('\n'); try strbuilder.append('\n');
if (mapbuilder) |*b| try b.append(.{ if (mapbuilder) |*b| try b.append(.{
.page = chunk.page, .page = chunk.page,
.y = y, .y = @intCast(y),
.x = chunk.page.data.size.cols - 1, .x = chunk.page.data.size.cols - 1,
}); });
} }
@ -3959,7 +3959,10 @@ test "Screen: resize (no reflow) less rows trims blank lines" {
// Write only a background color into the remaining rows // Write only a background color into the remaining rows
for (1..s.pages.rows) |y| { for (1..s.pages.rows) |y| {
const list_cell = s.pages.getCell(.{ .active = .{ .x = 0, .y = y } }).?; const list_cell = s.pages.getCell(.{ .active = .{
.x = 0,
.y = @intCast(y),
} }).?;
list_cell.cell.* = .{ list_cell.cell.* = .{
.content_tag = .bg_color_rgb, .content_tag = .bg_color_rgb,
.content = .{ .color_rgb = .{ .r = 0xFF, .g = 0, .b = 0 } }, .content = .{ .color_rgb = .{ .r = 0xFF, .g = 0, .b = 0 } },
@ -3991,7 +3994,10 @@ test "Screen: resize (no reflow) more rows trims blank lines" {
// Write only a background color into the remaining rows // Write only a background color into the remaining rows
for (1..s.pages.rows) |y| { for (1..s.pages.rows) |y| {
const list_cell = s.pages.getCell(.{ .active = .{ .x = 0, .y = y } }).?; const list_cell = s.pages.getCell(.{ .active = .{
.x = 0,
.y = @intCast(y),
} }).?;
list_cell.cell.* = .{ list_cell.cell.* = .{
.content_tag = .bg_color_rgb, .content_tag = .bg_color_rgb,
.content = .{ .color_rgb = .{ .r = 0xFF, .g = 0, .b = 0 } }, .content = .{ .color_rgb = .{ .r = 0xFF, .g = 0, .b = 0 } },
@ -4118,7 +4124,10 @@ test "Screen: resize (no reflow) more rows with soft wrapping" {
// Every second row should be wrapped // Every second row should be wrapped
for (0..6) |y| { for (0..6) |y| {
const list_cell = s.pages.getCell(.{ .screen = .{ .x = 0, .y = y } }).?; const list_cell = s.pages.getCell(.{ .screen = .{
.x = 0,
.y = @intCast(y),
} }).?;
const row = list_cell.row; const row = list_cell.row;
const wrapped = (y % 2 == 0); const wrapped = (y % 2 == 0);
try testing.expectEqual(wrapped, row.wrap); try testing.expectEqual(wrapped, row.wrap);
@ -4135,7 +4144,10 @@ test "Screen: resize (no reflow) more rows with soft wrapping" {
// Every second row should be wrapped // Every second row should be wrapped
for (0..6) |y| { for (0..6) |y| {
const list_cell = s.pages.getCell(.{ .screen = .{ .x = 0, .y = y } }).?; const list_cell = s.pages.getCell(.{ .screen = .{
.x = 0,
.y = @intCast(y),
} }).?;
const row = list_cell.row; const row = list_cell.row;
const wrapped = (y % 2 == 0); const wrapped = (y % 2 == 0);
try testing.expectEqual(wrapped, row.wrap); try testing.expectEqual(wrapped, row.wrap);

View File

@ -435,7 +435,7 @@ pub fn adjust(
const cells = next.page.data.getCells(rac.row); const cells = next.page.data.getCells(rac.row);
if (page.Cell.hasTextAny(cells)) { if (page.Cell.hasTextAny(cells)) {
end_pin.* = next; end_pin.* = next;
end_pin.x = cells.len - 1; end_pin.x = @intCast(cells.len - 1);
break; break;
} }
} }

View File

@ -4169,7 +4169,10 @@ test "Terminal: insertLines colors with bg color" {
} }
for (0..t.cols) |x| { for (0..t.cols) |x| {
const list_cell = t.screen.pages.getCell(.{ .active = .{ .x = x, .y = 1 } }).?; const list_cell = t.screen.pages.getCell(.{ .active = .{
.x = @intCast(x),
.y = 1,
} }).?;
try testing.expect(list_cell.cell.content_tag == .bg_color_rgb); try testing.expect(list_cell.cell.content_tag == .bg_color_rgb);
try testing.expectEqual(Cell.RGB{ try testing.expectEqual(Cell.RGB{
.r = 0xFF, .r = 0xFF,
@ -5297,7 +5300,10 @@ test "Terminal: index bottom of primary screen background sgr" {
defer testing.allocator.free(str); defer testing.allocator.free(str);
try testing.expectEqualStrings("\n\n\nA", str); try testing.expectEqualStrings("\n\n\nA", str);
for (0..5) |x| { for (0..5) |x| {
const list_cell = t.screen.pages.getCell(.{ .active = .{ .x = x, .y = 4 } }).?; const list_cell = t.screen.pages.getCell(.{ .active = .{
.x = @intCast(x),
.y = 4,
} }).?;
try testing.expect(list_cell.cell.content_tag == .bg_color_rgb); try testing.expect(list_cell.cell.content_tag == .bg_color_rgb);
try testing.expectEqual(Cell.RGB{ try testing.expectEqual(Cell.RGB{
.r = 0xFF, .r = 0xFF,
@ -5349,7 +5355,10 @@ test "Terminal: index bottom of scroll region with background SGR" {
} }
for (0..t.cols) |x| { for (0..t.cols) |x| {
const list_cell = t.screen.pages.getCell(.{ .active = .{ .x = x, .y = 2 } }).?; const list_cell = t.screen.pages.getCell(.{ .active = .{
.x = @intCast(x),
.y = 2,
} }).?;
try testing.expect(list_cell.cell.content_tag == .bg_color_rgb); try testing.expect(list_cell.cell.content_tag == .bg_color_rgb);
try testing.expectEqual(Cell.RGB{ try testing.expectEqual(Cell.RGB{
.r = 0xFF, .r = 0xFF,
@ -5961,7 +5970,10 @@ test "Terminal: deleteLines colors with bg color" {
} }
for (0..t.cols) |x| { for (0..t.cols) |x| {
const list_cell = t.screen.pages.getCell(.{ .active = .{ .x = x, .y = 4 } }).?; const list_cell = t.screen.pages.getCell(.{ .active = .{
.x = @intCast(x),
.y = 4,
} }).?;
try testing.expect(list_cell.cell.content_tag == .bg_color_rgb); try testing.expect(list_cell.cell.content_tag == .bg_color_rgb);
try testing.expectEqual(Cell.RGB{ try testing.expectEqual(Cell.RGB{
.r = 0xFF, .r = 0xFF,
@ -6148,7 +6160,10 @@ test "Terminal: deleteLines resets wrap" {
} }
for (0..t.rows) |y| { for (0..t.rows) |y| {
const list_cell = t.screen.pages.getCell(.{ .active = .{ .x = 0, .y = y } }).?; const list_cell = t.screen.pages.getCell(.{ .active = .{
.x = 0,
.y = @intCast(y),
} }).?;
const row = list_cell.row; const row = list_cell.row;
try testing.expect(!row.wrap); try testing.expect(!row.wrap);
} }
@ -7183,7 +7198,10 @@ test "Terminal: deleteChars preserves background sgr" {
try testing.expectEqualStrings("AB23", str); try testing.expectEqualStrings("AB23", str);
} }
for (t.cols - 2..t.cols) |x| { for (t.cols - 2..t.cols) |x| {
const list_cell = t.screen.pages.getCell(.{ .active = .{ .x = x, .y = 0 } }).?; const list_cell = t.screen.pages.getCell(.{ .active = .{
.x = @intCast(x),
.y = 0,
} }).?;
try testing.expect(list_cell.cell.content_tag == .bg_color_rgb); try testing.expect(list_cell.cell.content_tag == .bg_color_rgb);
try testing.expectEqual(Cell.RGB{ try testing.expectEqual(Cell.RGB{
.r = 0xFF, .r = 0xFF,
@ -7573,7 +7591,10 @@ test "Terminal: eraseLine right preserves background sgr" {
defer testing.allocator.free(str); defer testing.allocator.free(str);
try testing.expectEqualStrings("A", str); try testing.expectEqualStrings("A", str);
for (1..5) |x| { for (1..5) |x| {
const list_cell = t.screen.pages.getCell(.{ .active = .{ .x = x, .y = 0 } }).?; const list_cell = t.screen.pages.getCell(.{ .active = .{
.x = @intCast(x),
.y = 0,
} }).?;
try testing.expect(list_cell.cell.content_tag == .bg_color_rgb); try testing.expect(list_cell.cell.content_tag == .bg_color_rgb);
try testing.expectEqual(Cell.RGB{ try testing.expectEqual(Cell.RGB{
.r = 0xFF, .r = 0xFF,
@ -7727,7 +7748,10 @@ test "Terminal: eraseLine left preserves background sgr" {
defer testing.allocator.free(str); defer testing.allocator.free(str);
try testing.expectEqualStrings(" CDE", str); try testing.expectEqualStrings(" CDE", str);
for (0..2) |x| { for (0..2) |x| {
const list_cell = t.screen.pages.getCell(.{ .active = .{ .x = x, .y = 0 } }).?; const list_cell = t.screen.pages.getCell(.{ .active = .{
.x = @intCast(x),
.y = 0,
} }).?;
try testing.expect(list_cell.cell.content_tag == .bg_color_rgb); try testing.expect(list_cell.cell.content_tag == .bg_color_rgb);
try testing.expectEqual(Cell.RGB{ try testing.expectEqual(Cell.RGB{
.r = 0xFF, .r = 0xFF,
@ -7847,7 +7871,10 @@ test "Terminal: eraseLine complete preserves background sgr" {
defer testing.allocator.free(str); defer testing.allocator.free(str);
try testing.expectEqualStrings("", str); try testing.expectEqualStrings("", str);
for (0..5) |x| { for (0..5) |x| {
const list_cell = t.screen.pages.getCell(.{ .active = .{ .x = x, .y = 0 } }).?; const list_cell = t.screen.pages.getCell(.{ .active = .{
.x = @intCast(x),
.y = 0,
} }).?;
try testing.expect(list_cell.cell.content_tag == .bg_color_rgb); try testing.expect(list_cell.cell.content_tag == .bg_color_rgb);
try testing.expectEqual(Cell.RGB{ try testing.expectEqual(Cell.RGB{
.r = 0xFF, .r = 0xFF,
@ -8096,7 +8123,10 @@ test "Terminal: eraseDisplay erase below preserves SGR bg" {
defer testing.allocator.free(str); defer testing.allocator.free(str);
try testing.expectEqualStrings("ABC\nD", str); try testing.expectEqualStrings("ABC\nD", str);
for (1..5) |x| { for (1..5) |x| {
const list_cell = t.screen.pages.getCell(.{ .active = .{ .x = x, .y = 1 } }).?; const list_cell = t.screen.pages.getCell(.{ .active = .{
.x = @intCast(x),
.y = 1,
} }).?;
try testing.expect(list_cell.cell.content_tag == .bg_color_rgb); try testing.expect(list_cell.cell.content_tag == .bg_color_rgb);
try testing.expectEqual(Cell.RGB{ try testing.expectEqual(Cell.RGB{
.r = 0xFF, .r = 0xFF,
@ -8271,7 +8301,10 @@ test "Terminal: eraseDisplay erase above preserves SGR bg" {
defer testing.allocator.free(str); defer testing.allocator.free(str);
try testing.expectEqualStrings("\n F\nGHI", str); try testing.expectEqualStrings("\n F\nGHI", str);
for (0..2) |x| { for (0..2) |x| {
const list_cell = t.screen.pages.getCell(.{ .active = .{ .x = x, .y = 1 } }).?; const list_cell = t.screen.pages.getCell(.{ .active = .{
.x = @intCast(x),
.y = 1,
} }).?;
try testing.expect(list_cell.cell.content_tag == .bg_color_rgb); try testing.expect(list_cell.cell.content_tag == .bg_color_rgb);
try testing.expectEqual(Cell.RGB{ try testing.expectEqual(Cell.RGB{
.r = 0xFF, .r = 0xFF,

View File

@ -5,6 +5,7 @@ const ArenaAllocator = std.heap.ArenaAllocator;
const terminal = @import("../main.zig"); const terminal = @import("../main.zig");
const point = @import("../point.zig"); const point = @import("../point.zig");
const size = @import("../size.zig");
const command = @import("graphics_command.zig"); const command = @import("graphics_command.zig");
const PageList = @import("../PageList.zig"); const PageList = @import("../PageList.zig");
const Screen = @import("../Screen.zig"); const Screen = @import("../Screen.zig");
@ -265,13 +266,13 @@ pub const ImageStorage = struct {
); );
}, },
.intersect_cell => |v| { .intersect_cell => |v| intersect_cell: {
self.deleteIntersecting( self.deleteIntersecting(
alloc, alloc,
t, t,
.{ .active = .{ .{ .active = .{
.x = v.x, .x = std.math.cast(size.CellCountInt, v.x) orelse break :intersect_cell,
.y = v.y, .y = std.math.cast(size.CellCountInt, v.y) orelse break :intersect_cell,
} }, } },
v.delete, v.delete,
{}, {},
@ -279,13 +280,13 @@ pub const ImageStorage = struct {
); );
}, },
.intersect_cell_z => |v| { .intersect_cell_z => |v| intersect_cell_z: {
self.deleteIntersecting( self.deleteIntersecting(
alloc, alloc,
t, t,
.{ .active = .{ .{ .active = .{
.x = v.x, .x = std.math.cast(size.CellCountInt, v.x) orelse break :intersect_cell_z,
.y = v.y, .y = std.math.cast(size.CellCountInt, v.y) orelse break :intersect_cell_z,
} }, } },
v.delete, v.delete,
v.z, v.z,
@ -317,7 +318,7 @@ pub const ImageStorage = struct {
// v.y is in active coords so we want to convert it to a pin // v.y is in active coords so we want to convert it to a pin
// so we can compare by page offsets. // so we can compare by page offsets.
const target_pin = t.screen.pages.pin(.{ .active = .{ const target_pin = t.screen.pages.pin(.{ .active = .{
.y = v.y, .y = std.math.cast(size.CellCountInt, v.y) orelse break :row,
} }) orelse break :row; } }) orelse break :row;
var it = self.placements.iterator(); var it = self.placements.iterator();

View File

@ -1,6 +1,7 @@
const std = @import("std"); const std = @import("std");
const Allocator = std.mem.Allocator; const Allocator = std.mem.Allocator;
const assert = std.debug.assert; const assert = std.debug.assert;
const size = @import("size.zig");
/// The possible reference locations for a point. When someone says "(42, 80)" in the context of a terminal, that could mean multiple /// The possible reference locations for a point. When someone says "(42, 80)" in the context of a terminal, that could mean multiple
/// things: it is in the current visible viewport? the current active /// things: it is in the current visible viewport? the current active
@ -65,8 +66,8 @@ pub const Point = union(Tag) {
}; };
pub const Coordinate = struct { pub const Coordinate = struct {
x: usize = 0, x: size.CellCountInt = 0,
y: usize = 0, y: size.CellCountInt = 0,
pub fn eql(self: Coordinate, other: Coordinate) bool { pub fn eql(self: Coordinate, other: Coordinate) bool {
return self.x == other.x and self.y == other.y; return self.x == other.x and self.y == other.y;