terminal/new: pages have a size

This commit is contained in:
Mitchell Hashimoto
2024-02-21 19:26:44 -08:00
parent 01f2a9b39a
commit 06e88a975b
4 changed files with 40 additions and 26 deletions

View File

@ -8,6 +8,7 @@ const Allocator = std.mem.Allocator;
const assert = std.debug.assert;
const point = @import("point.zig");
const pagepkg = @import("page.zig");
const size = @import("size.zig");
const Page = pagepkg.Page;
/// The number of PageList.Nodes we preheat the pool with. A node is
@ -55,13 +56,13 @@ active: RowOffset,
/// The current desired screen dimensions. I say "desired" because individual
/// pages may still be a different size and not yet reflowed since we lazily
/// reflow text.
cols: usize,
rows: usize,
cols: size.CellCountInt,
rows: size.CellCountInt,
pub fn init(
alloc: Allocator,
cols: usize,
rows: usize,
cols: size.CellCountInt,
rows: size.CellCountInt,
max_scrollback: usize,
) !PageList {
_ = max_scrollback;

View File

@ -24,8 +24,8 @@ cursor: Cursor,
/// The cursor position.
const Cursor = struct {
// The x/y position within the viewport.
x: usize,
y: usize,
x: size.CellCountInt,
y: size.CellCountInt,
/// The "last column flag (LCF)" as its called. If this is set then the
/// next character print will force a soft-wrap.
@ -47,8 +47,8 @@ const Cursor = struct {
/// Initialize a new screen.
pub fn init(
alloc: Allocator,
cols: usize,
rows: usize,
cols: size.CellCountInt,
rows: size.CellCountInt,
max_scrollback: usize,
) !Screen {
// Initialize our backing pages. This will initialize the viewport.
@ -106,7 +106,7 @@ pub fn cursorDown(self: *Screen) void {
}
/// Move the cursor to some absolute position.
pub fn cursorHorizontalAbsolute(self: *Screen, x: usize) void {
pub fn cursorHorizontalAbsolute(self: *Screen, x: size.CellCountInt) void {
assert(x < self.pages.cols);
const page_rac = self.cursor.page_offset.rowAndCell(x);

View File

@ -20,6 +20,7 @@ const Tabstops = @import("../Tabstops.zig");
const color = @import("../color.zig");
const mouse_shape = @import("../mouse_shape.zig");
const size = @import("size.zig");
const pagepkg = @import("page.zig");
const style = @import("style.zig");
const Screen = @import("Screen.zig");
@ -65,8 +66,8 @@ status_display: ansi.StatusDisplay = .main,
tabstops: Tabstops,
/// The size of the terminal.
rows: usize,
cols: usize,
rows: size.CellCountInt,
cols: size.CellCountInt,
/// The size of the screen in pixels. This is used for pty events and images
width_px: u32 = 0,
@ -155,18 +156,18 @@ pub const MouseFormat = enum(u3) {
pub const ScrollingRegion = struct {
// Top and bottom of the scroll region (0-indexed)
// Precondition: top < bottom
top: usize,
bottom: usize,
top: size.CellCountInt,
bottom: size.CellCountInt,
// Left/right scroll regions.
// Precondition: right > left
// Precondition: right <= cols - 1
left: usize,
right: usize,
left: size.CellCountInt,
right: size.CellCountInt,
};
/// Initialize a new terminal.
pub fn init(alloc: Allocator, cols: usize, rows: usize) !Terminal {
pub fn init(alloc: Allocator, cols: size.CellCountInt, rows: size.CellCountInt) !Terminal {
return Terminal{
.cols = cols,
.rows = rows,

View File

@ -70,7 +70,13 @@ pub const Page = struct {
/// The available set of styles in use on this page.
styles: style.Set,
/// The capacity of this page.
/// The current dimensions of the page. The capacity may be larger
/// than this. This allows us to allocate a larger page than necessary
/// and also to resize a page smaller witout reallocating.
size: Size,
/// The capacity of this page. This is the full size of the backing
/// memory and is fixed at page creation time.
capacity: Capacity,
/// The allocator to use for multi-codepoint grapheme data. We use
@ -85,11 +91,17 @@ pub const Page = struct {
const grapheme_bytes_default = grapheme_count_default * grapheme_chunk;
const GraphemeMap = AutoOffsetHashMap(Offset(Cell), Offset(u21).Slice);
/// The size of this page.
pub const Size = struct {
cols: size.CellCountInt,
rows: size.CellCountInt,
};
/// Capacity of this page.
pub const Capacity = struct {
/// Number of columns and rows we can know about.
cols: usize,
rows: usize,
cols: size.CellCountInt,
rows: size.CellCountInt,
/// Number of unique styles that can be used on this page.
styles: u16 = 16,
@ -99,8 +111,7 @@ pub const Page = struct {
};
/// Initialize a new page, allocating the required backing memory.
/// It is HIGHLY RECOMMENDED you use a page_allocator as the allocator
/// but any allocator is allowed.
/// The size of the initialized page defaults to the full capacity.
pub fn init(alloc: Allocator, cap: Capacity) !Page {
const l = layout(cap);
const backing = try alloc.alignedAlloc(u8, std.mem.page_size, l.total_size);
@ -138,6 +149,7 @@ pub const Page = struct {
buf.add(l.grapheme_map_start),
l.grapheme_map_layout,
),
.size = .{ .cols = cap.cols, .rows = cap.rows },
.capacity = cap,
};
}
@ -149,7 +161,7 @@ pub const Page = struct {
/// Get a single row. y must be valid.
pub fn getRow(self: *const Page, y: usize) *Row {
assert(y < self.capacity.rows);
assert(y < self.size.rows);
return &self.rows.ptr(self.memory)[y];
}
@ -163,7 +175,7 @@ pub const Page = struct {
}
const cells = row.cells.ptr(self.memory);
return cells[0..self.capacity.cols];
return cells[0..self.size.cols];
}
/// Get the row and cell for the given X/Y within this page.
@ -171,8 +183,8 @@ pub const Page = struct {
row: *Row,
cell: *Cell,
} {
assert(y < self.capacity.rows);
assert(x < self.capacity.cols);
assert(y < self.size.rows);
assert(x < self.size.cols);
const rows = self.rows.ptr(self.memory);
const row = &rows[y];
@ -199,7 +211,7 @@ pub const Page = struct {
const rows_start = 0;
const rows_end = rows_start + (cap.rows * @sizeOf(Row));
const cells_count = cap.cols * cap.rows;
const cells_count: usize = @intCast(cap.cols * cap.rows);
const cells_start = alignForward(usize, rows_end, @alignOf(Cell));
const cells_end = cells_start + (cells_count * @sizeOf(Cell));