mirror of
https://github.com/ghostty-org/ghostty.git
synced 2025-07-16 16:56:09 +03:00
terminal/new: page has graphemes attached
This commit is contained in:
@ -125,7 +125,7 @@ pub fn BitmapAllocator(comptime chunk_size: comptime_int) type {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const Layout = struct {
|
pub const Layout = struct {
|
||||||
total_size: usize,
|
total_size: usize,
|
||||||
bitmap_count: usize,
|
bitmap_count: usize,
|
||||||
bitmap_start: usize,
|
bitmap_start: usize,
|
||||||
|
@ -8,6 +8,7 @@ const size = @import("size.zig");
|
|||||||
const getOffset = size.getOffset;
|
const getOffset = size.getOffset;
|
||||||
const Offset = size.Offset;
|
const Offset = size.Offset;
|
||||||
const OffsetBuf = size.OffsetBuf;
|
const OffsetBuf = size.OffsetBuf;
|
||||||
|
const BitmapAllocator = @import("bitmap_allocator.zig").BitmapAllocator;
|
||||||
const hash_map = @import("hash_map.zig");
|
const hash_map = @import("hash_map.zig");
|
||||||
const AutoOffsetHashMap = hash_map.AutoOffsetHashMap;
|
const AutoOffsetHashMap = hash_map.AutoOffsetHashMap;
|
||||||
const alignForward = std.mem.alignForward;
|
const alignForward = std.mem.alignForward;
|
||||||
@ -57,7 +58,8 @@ pub const Page = struct {
|
|||||||
/// any cell that has more than one codepoint will be stored. This is
|
/// any cell that has more than one codepoint will be stored. This is
|
||||||
/// relatively rare (typically only emoji) so this defaults to a very small
|
/// relatively rare (typically only emoji) so this defaults to a very small
|
||||||
/// size and we force page realloc when it grows.
|
/// size and we force page realloc when it grows.
|
||||||
__todo_graphemes: void = {},
|
grapheme_alloc: GraphemeAlloc,
|
||||||
|
grapheme_map: GraphemeMap,
|
||||||
|
|
||||||
/// The available set of styles in use on this page.
|
/// The available set of styles in use on this page.
|
||||||
styles: style.Set,
|
styles: style.Set,
|
||||||
@ -65,6 +67,18 @@ pub const Page = struct {
|
|||||||
/// The capacity of this page.
|
/// The capacity of this page.
|
||||||
capacity: Capacity,
|
capacity: Capacity,
|
||||||
|
|
||||||
|
/// The allocator to use for multi-codepoint grapheme data. We use
|
||||||
|
/// a chunk size of 4 codepoints. It'd be best to set this empirically
|
||||||
|
/// but it is currently set based on vibes. My thinking around 4 codepoints
|
||||||
|
/// is that most skin-tone emoji are <= 4 codepoints, letter combiners
|
||||||
|
/// are usually <= 4 codepoints, and 4 codepoints is a nice power of two
|
||||||
|
/// for alignment.
|
||||||
|
const grapheme_chunk = 4 * @sizeOf(u21);
|
||||||
|
const GraphemeAlloc = BitmapAllocator(grapheme_chunk);
|
||||||
|
const grapheme_count_default = GraphemeAlloc.bitmap_bit_size;
|
||||||
|
const grapheme_bytes_default = grapheme_count_default * grapheme_chunk;
|
||||||
|
const GraphemeMap = AutoOffsetHashMap(Offset(Cell), Offset(u21).Slice);
|
||||||
|
|
||||||
/// Capacity of this page.
|
/// Capacity of this page.
|
||||||
pub const Capacity = struct {
|
pub const Capacity = struct {
|
||||||
/// Number of columns and rows we can know about.
|
/// Number of columns and rows we can know about.
|
||||||
@ -72,7 +86,10 @@ pub const Page = struct {
|
|||||||
rows: usize,
|
rows: usize,
|
||||||
|
|
||||||
/// Number of unique styles that can be used on this page.
|
/// Number of unique styles that can be used on this page.
|
||||||
styles: u16,
|
styles: u16 = 16,
|
||||||
|
|
||||||
|
/// Number of bytes to allocate for grapheme data.
|
||||||
|
grapheme_bytes: usize = grapheme_bytes_default,
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Initialize a new page, allocating the required backing memory.
|
/// Initialize a new page, allocating the required backing memory.
|
||||||
@ -103,7 +120,18 @@ pub const Page = struct {
|
|||||||
.memory = backing,
|
.memory = backing,
|
||||||
.rows = rows,
|
.rows = rows,
|
||||||
.cells = cells,
|
.cells = cells,
|
||||||
.styles = style.Set.init(buf.add(l.styles_start), l.styles_layout),
|
.styles = style.Set.init(
|
||||||
|
buf.add(l.styles_start),
|
||||||
|
l.styles_layout,
|
||||||
|
),
|
||||||
|
.grapheme_alloc = GraphemeAlloc.init(
|
||||||
|
buf.add(l.grapheme_alloc_start),
|
||||||
|
l.grapheme_alloc_layout,
|
||||||
|
),
|
||||||
|
.grapheme_map = GraphemeMap.init(
|
||||||
|
buf.add(l.grapheme_map_start),
|
||||||
|
l.grapheme_map_layout,
|
||||||
|
),
|
||||||
.capacity = cap,
|
.capacity = cap,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -153,6 +181,10 @@ pub const Page = struct {
|
|||||||
cells_start: usize,
|
cells_start: usize,
|
||||||
styles_start: usize,
|
styles_start: usize,
|
||||||
styles_layout: style.Set.Layout,
|
styles_layout: style.Set.Layout,
|
||||||
|
grapheme_alloc_start: usize,
|
||||||
|
grapheme_alloc_layout: GraphemeAlloc.Layout,
|
||||||
|
grapheme_map_start: usize,
|
||||||
|
grapheme_map_layout: GraphemeMap.Layout,
|
||||||
};
|
};
|
||||||
|
|
||||||
/// The memory layout for a page given a desired minimum cols
|
/// The memory layout for a page given a desired minimum cols
|
||||||
@ -169,7 +201,16 @@ pub const Page = struct {
|
|||||||
const styles_start = alignForward(usize, cells_end, style.Set.base_align);
|
const styles_start = alignForward(usize, cells_end, style.Set.base_align);
|
||||||
const styles_end = styles_start + styles_layout.total_size;
|
const styles_end = styles_start + styles_layout.total_size;
|
||||||
|
|
||||||
const total_size = styles_end;
|
const grapheme_alloc_layout = GraphemeAlloc.layout(cap.grapheme_bytes);
|
||||||
|
const grapheme_alloc_start = alignForward(usize, styles_end, GraphemeAlloc.base_align);
|
||||||
|
const grapheme_alloc_end = grapheme_alloc_start + grapheme_alloc_layout.total_size;
|
||||||
|
|
||||||
|
const grapheme_count = @divFloor(cap.grapheme_bytes, grapheme_chunk);
|
||||||
|
const grapheme_map_layout = GraphemeMap.layout(@intCast(grapheme_count));
|
||||||
|
const grapheme_map_start = alignForward(usize, grapheme_alloc_end, GraphemeMap.base_align);
|
||||||
|
const grapheme_map_end = grapheme_map_start + grapheme_map_layout.total_size;
|
||||||
|
|
||||||
|
const total_size = grapheme_map_end;
|
||||||
|
|
||||||
return .{
|
return .{
|
||||||
.total_size = total_size,
|
.total_size = total_size,
|
||||||
@ -177,6 +218,10 @@ pub const Page = struct {
|
|||||||
.cells_start = cells_start,
|
.cells_start = cells_start,
|
||||||
.styles_start = styles_start,
|
.styles_start = styles_start,
|
||||||
.styles_layout = styles_layout,
|
.styles_layout = styles_layout,
|
||||||
|
.grapheme_alloc_start = grapheme_alloc_start,
|
||||||
|
.grapheme_alloc_layout = grapheme_alloc_layout,
|
||||||
|
.grapheme_map_start = grapheme_map_start,
|
||||||
|
.grapheme_map_layout = grapheme_map_layout,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -24,6 +24,12 @@ pub fn Offset(comptime T: type) type {
|
|||||||
|
|
||||||
offset: OffsetInt = 0,
|
offset: OffsetInt = 0,
|
||||||
|
|
||||||
|
/// A slice of type T that stores via a base offset and len.
|
||||||
|
pub const Slice = struct {
|
||||||
|
offset: Self,
|
||||||
|
len: usize,
|
||||||
|
};
|
||||||
|
|
||||||
/// Returns a pointer to the start of the data, properly typed.
|
/// Returns a pointer to the start of the data, properly typed.
|
||||||
pub fn ptr(self: Self, base: anytype) [*]T {
|
pub fn ptr(self: Self, base: anytype) [*]T {
|
||||||
// The offset must be properly aligned for the type since
|
// The offset must be properly aligned for the type since
|
||||||
|
Reference in New Issue
Block a user