parent
f7496654ae
commit
a9d4fed205
3 changed files with 35 additions and 18 deletions
|
@ -5,9 +5,15 @@ const Node = struct {
|
|||
prev: ?u32,
|
||||
next: ?u32,
|
||||
codepoint: ?u21,
|
||||
right_half: ?bool,
|
||||
};
|
||||
|
||||
map: std.AutoHashMapUnmanaged(u21, u32) = .{},
|
||||
const MapKey = struct {
|
||||
codepoint: u21,
|
||||
right_half: bool,
|
||||
};
|
||||
|
||||
map: std.AutoHashMapUnmanaged(MapKey, u32) = .{},
|
||||
nodes: []Node,
|
||||
front: u32,
|
||||
back: u32,
|
||||
|
@ -25,13 +31,14 @@ pub fn init(allocator: std.mem.Allocator, capacity: u32) error{OutOfMemory}!Glyp
|
|||
|
||||
pub fn clearRetainingCapacity(self: *GlyphIndexCache) void {
|
||||
self.map.clearRetainingCapacity();
|
||||
self.nodes[0] = .{ .prev = null, .next = 1, .codepoint = null };
|
||||
self.nodes[self.nodes.len - 1] = .{ .prev = @intCast(self.nodes.len - 2), .next = null, .codepoint = null };
|
||||
self.nodes[0] = .{ .prev = null, .next = 1, .codepoint = null, .right_half = null };
|
||||
self.nodes[self.nodes.len - 1] = .{ .prev = @intCast(self.nodes.len - 2), .next = null, .codepoint = null, .right_half = null };
|
||||
for (self.nodes[1 .. self.nodes.len - 1], 1..) |*node, index| {
|
||||
node.* = .{
|
||||
.prev = @intCast(index - 1),
|
||||
.next = @intCast(index + 1),
|
||||
.codepoint = null,
|
||||
.right_half = null,
|
||||
};
|
||||
}
|
||||
self.front = 0;
|
||||
|
@ -51,12 +58,12 @@ const Reserved = struct {
|
|||
index: u32,
|
||||
replaced: ?u21,
|
||||
};
|
||||
pub fn reserve(self: *GlyphIndexCache, allocator: std.mem.Allocator, codepoint: u21) error{OutOfMemory}!union(enum) {
|
||||
pub fn reserve(self: *GlyphIndexCache, allocator: std.mem.Allocator, codepoint: u21, right_half: bool) error{OutOfMemory}!union(enum) {
|
||||
newly_reserved: Reserved,
|
||||
already_reserved: u32,
|
||||
} {
|
||||
{
|
||||
const entry = try self.map.getOrPut(allocator, codepoint);
|
||||
const entry = try self.map.getOrPut(allocator, .{ .codepoint = codepoint, .right_half = right_half });
|
||||
if (entry.found_existing) {
|
||||
self.moveToBack(entry.value_ptr.*);
|
||||
return .{ .already_reserved = entry.value_ptr.* };
|
||||
|
@ -69,7 +76,7 @@ pub fn reserve(self: *GlyphIndexCache, allocator: std.mem.Allocator, codepoint:
|
|||
const replaced = self.nodes[self.front].codepoint;
|
||||
self.nodes[self.front].codepoint = codepoint;
|
||||
if (replaced) |r| {
|
||||
const removed = self.map.remove(r);
|
||||
const removed = self.map.remove(.{ .codepoint = r, .right_half = self.nodes[self.front].right_half orelse false });
|
||||
std.debug.assert(removed);
|
||||
}
|
||||
const save_front = self.front;
|
||||
|
|
|
@ -149,7 +149,7 @@ pub const WindowState = struct {
|
|||
}
|
||||
|
||||
// TODO: this should take a utf8 graphme instead
|
||||
pub fn generateGlyph(state: *WindowState, font: Font, codepoint: u21) u32 {
|
||||
pub fn generateGlyph(state: *WindowState, font: Font, codepoint: u21, right_half: bool) u32 {
|
||||
// for now we'll just use 1 texture and leverage the entire thing
|
||||
const texture_cell_count: XY(u16) = getD3d11TextureMaxCellCount(font.cell_size);
|
||||
const texture_cell_count_total: u32 =
|
||||
|
@ -187,12 +187,15 @@ pub const WindowState = struct {
|
|||
switch (glyph_index_cache.reserve(
|
||||
global.glyph_cache_arena.allocator(),
|
||||
codepoint,
|
||||
right_half,
|
||||
) catch |e| oom(e)) {
|
||||
.newly_reserved => |reserved| {
|
||||
// var render_success = false;
|
||||
// defer if (!render_success) state.glyph_index_cache.remove(reserved.index);
|
||||
const pos: XY(u16) = cellPosFromIndex(reserved.index, texture_cell_count.x);
|
||||
const coord = coordFromCellPos(font.cell_size, pos);
|
||||
var staging_size = font.cell_size;
|
||||
staging_size.x = if (right_half) staging_size.x * 2 else staging_size.x;
|
||||
const staging = global.staging_texture.update(font.cell_size);
|
||||
var utf8_buf: [7]u8 = undefined;
|
||||
const utf8_len: u3 = std.unicode.utf8Encode(codepoint, &utf8_buf) catch |e| std.debug.panic(
|
||||
|
@ -204,10 +207,10 @@ pub const WindowState = struct {
|
|||
utf8_buf[0..utf8_len],
|
||||
);
|
||||
const box: win32.D3D11_BOX = .{
|
||||
.left = 0,
|
||||
.left = if (right_half) font.cell_size.x else 0,
|
||||
.top = 0,
|
||||
.front = 0,
|
||||
.right = font.cell_size.x,
|
||||
.right = if (right_half) font.cell_size.x * 2 else font.cell_size.x,
|
||||
.bottom = font.cell_size.y,
|
||||
.back = 1,
|
||||
};
|
||||
|
@ -289,7 +292,7 @@ pub fn paint(
|
|||
}
|
||||
|
||||
const copy_col_count: u16 = @min(col_count, shader_col_count);
|
||||
const blank_space_glyph_index = state.generateGlyph(font, ' ');
|
||||
const blank_space_glyph_index = state.generateGlyph(font, ' ', false);
|
||||
|
||||
const cell_count: u32 = @as(u32, shader_col_count) * @as(u32, shader_row_count);
|
||||
state.shader_cells.updateCount(cell_count);
|
||||
|
|
|
@ -1081,19 +1081,26 @@ fn WndProc(
|
|||
global.render_cells_arena.allocator(),
|
||||
global.screen.buf.len,
|
||||
) catch |e| oom(e);
|
||||
var prev_width: usize = 1;
|
||||
var prev_cell: render.Cell = undefined;
|
||||
for (global.screen.buf, global.render_cells.items) |*screen_cell, *render_cell| {
|
||||
const width = screen_cell.char.width;
|
||||
const codepoint = if (std.unicode.utf8ValidateSlice(screen_cell.char.grapheme))
|
||||
std.unicode.wtf8Decode(screen_cell.char.grapheme) catch std.unicode.replacement_character
|
||||
else
|
||||
std.unicode.replacement_character;
|
||||
render_cell.* = .{
|
||||
.glyph_index = state.render_state.generateGlyph(
|
||||
font,
|
||||
codepoint,
|
||||
),
|
||||
.background = renderColorFromVaxis(screen_cell.style.bg),
|
||||
.foreground = renderColorFromVaxis(screen_cell.style.fg),
|
||||
};
|
||||
if (prev_width > 1) {
|
||||
render_cell.* = prev_cell;
|
||||
render_cell.glyph_index = state.render_state.generateGlyph(font, codepoint, true);
|
||||
} else {
|
||||
render_cell.* = .{
|
||||
.glyph_index = state.render_state.generateGlyph(font, codepoint, false),
|
||||
.background = renderColorFromVaxis(screen_cell.style.bg),
|
||||
.foreground = renderColorFromVaxis(screen_cell.style.fg),
|
||||
};
|
||||
}
|
||||
prev_width = width;
|
||||
prev_cell = render_cell.*;
|
||||
}
|
||||
render.paint(
|
||||
&state.render_state,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue