diff --git a/ly-ui/src/TerminalBuffer.zig b/ly-ui/src/TerminalBuffer.zig index 565593b..19805ec 100644 --- a/ly-ui/src/TerminalBuffer.zig +++ b/ly-ui/src/TerminalBuffer.zig @@ -381,6 +381,15 @@ pub fn setCell(x: usize, y: usize, cell: Cell) void { ); } +pub fn setCellBoundsChecked(self: *TerminalBuffer, x: usize, y: usize, cell: Cell) void { + const width = self.width; + const height = self.height; + + if (0 <= x and x < width and 0 <= y and y < height) { + cell.put(x, y); + } +} + pub fn reclaim(self: TerminalBuffer) !void { if (self.termios) |termios| { // Take back control of the TTY diff --git a/src/animations/DurFile.zig b/src/animations/DurFile.zig index 2de518e..675ea94 100644 --- a/src/animations/DurFile.zig +++ b/src/animations/DurFile.zig @@ -538,25 +538,19 @@ fn draw(self: *DurFile) void { const current_frame = self.dur_movie.frames.items[self.frames]; - const buf_width: u32 = @intCast(self.terminal_buffer.width); - const buf_height: u32 = @intCast(self.terminal_buffer.height); - // y is used as an iterator in the durformat, while cell_y gives us the correct placement for the cell (same for x) - const start_pos_y: u64 = @max(0, -self.start_pos[VEC_Y]); - const lines: u64 = @intCast(self.dur_movie.lines.?); - const end_pos_y: u64 = @intCast(@min(lines, buf_height - self.start_pos[VEC_Y])); - for (start_pos_y..end_pos_y) |y| { + for (0..@intCast(self.dur_movie.lines.?)) |y| { const y_offset_i = @as(i32, @intCast(y)) + self.start_pos[VEC_Y]; - const cell_y: u32 = @intCast(y_offset_i); + const cell_y: u32 = if (y_offset_i >= 0) @intCast(y_offset_i) else continue; var iter = std.unicode.Utf8View.initUnchecked(current_frame.contents[y]).iterator(); - const start_pos_x: u64 = @max(0, -self.start_pos[VEC_X]); - const columns: u64 = @intCast(self.dur_movie.columns.?); - const end_pos_x: u64 = @intCast(@min(columns, buf_width - self.start_pos[VEC_X])); - for (start_pos_x..end_pos_x) |x| { + for (0..@intCast(self.dur_movie.columns.?)) |x| { const x_offset_i = @as(i32, @intCast(x)) + self.start_pos[VEC_X]; - const cell_x: u32 = @intCast(x_offset_i); + const cell_x: u32 = if (x_offset_i >= 0) @intCast(x_offset_i) else { + _ = iter.nextCodepoint().?; + continue; + }; const codepoint: u21 = iter.nextCodepoint().?; const color_map = current_frame.colorMap[x][y]; @@ -573,7 +567,7 @@ fn draw(self: *DurFile) void { const cell = Cell{ .ch = @intCast(codepoint), .fg = fg_color, .bg = bg_color }; - cell.put(cell_x, cell_y); + self.terminal_buffer.setCellBoundsChecked(cell_x, cell_y, cell); } }