terminal/kitty-gfx: we need to use rect, not sel

This commit is contained in:
Mitchell Hashimoto
2023-08-23 11:07:48 -07:00
parent 98f1b55ea4
commit 6f7a9c4523
2 changed files with 65 additions and 2 deletions

View File

@ -5,6 +5,7 @@ const Allocator = std.mem.Allocator;
const ArenaAllocator = std.heap.ArenaAllocator; const ArenaAllocator = std.heap.ArenaAllocator;
const command = @import("graphics_command.zig"); const command = @import("graphics_command.zig");
const point = @import("../point.zig");
const internal_os = @import("../../os/main.zig"); const internal_os = @import("../../os/main.zig");
const stb = @import("../../stb/main.zig"); const stb = @import("../../stb/main.zig");
@ -382,6 +383,22 @@ pub const Image = struct {
} }
}; };
/// The rect taken up by some image placement, in grid cells. This will
/// be rounded up to the nearest grid cell since we can't place images
/// in partial grid cells.
pub const Rect = struct {
top_left: point.ScreenPoint = .{},
bottom_right: point.ScreenPoint = .{},
/// True if the rect contains a given screen point.
pub fn contains(self: Rect, p: point.ScreenPoint) bool {
return p.y >= self.top_left.y and
p.y <= self.bottom_right.y and
p.x >= self.top_left.x and
p.x <= self.bottom_right.x;
}
};
/// Easy base64 encoding function. /// Easy base64 encoding function.
fn testB64(alloc: Allocator, data: []const u8) ![]const u8 { fn testB64(alloc: Allocator, data: []const u8) ![]const u8 {
const B64Encoder = std.base64.standard.Encoder; const B64Encoder = std.base64.standard.Encoder;

View File

@ -9,6 +9,7 @@ const command = @import("graphics_command.zig");
const Screen = @import("../Screen.zig"); const Screen = @import("../Screen.zig");
const LoadingImage = @import("graphics_image.zig").LoadingImage; const LoadingImage = @import("graphics_image.zig").LoadingImage;
const Image = @import("graphics_image.zig").Image; const Image = @import("graphics_image.zig").Image;
const Rect = @import("graphics_image.zig").Rect;
const Command = command.Command; const Command = command.Command;
const ScreenPoint = point.ScreenPoint; const ScreenPoint = point.ScreenPoint;
@ -218,8 +219,8 @@ pub const ImageStorage = struct {
var it = self.placements.iterator(); var it = self.placements.iterator();
while (it.next()) |entry| { while (it.next()) |entry| {
const img = self.imageById(entry.key_ptr.image_id) orelse continue; const img = self.imageById(entry.key_ptr.image_id) orelse continue;
const sel = entry.value_ptr.selection(img, t); const rect = entry.value_ptr.rect(img, t);
if (sel.contains(p)) { if (rect.contains(p)) {
if (filter) |f| if (!f(filter_ctx, entry.value_ptr.*)) continue; if (filter) |f| if (!f(filter_ctx, entry.value_ptr.*)) continue;
self.placements.removeByPtr(entry.key_ptr); self.placements.removeByPtr(entry.key_ptr);
if (delete_unused) self.deleteIfUnused(alloc, img.id); if (delete_unused) self.deleteIfUnused(alloc, img.id);
@ -256,6 +257,51 @@ pub const ImageStorage = struct {
/// The z-index for this placement. /// The z-index for this placement.
z: i32 = 0, z: i32 = 0,
/// Returns a selection of the entire rectangle this placement
/// occupies within the screen.
pub fn rect(
self: Placement,
image: Image,
t: *const terminal.Terminal,
) Rect {
// If we have columns/rows specified we can simplify this whole thing.
if (self.columns > 0 and self.rows > 0) {
return .{
.top_left = self.point,
.bottom_right = .{
.x = @min(self.point.x + self.columns, t.cols - 1),
.y = self.point.y + self.rows,
},
};
}
// Calculate our cell size.
const terminal_width_f64: f64 = @floatFromInt(t.width_px);
const terminal_height_f64: f64 = @floatFromInt(t.height_px);
const grid_columns_f64: f64 = @floatFromInt(t.cols);
const grid_rows_f64: f64 = @floatFromInt(t.rows);
const cell_width_f64 = terminal_width_f64 / grid_columns_f64;
const cell_height_f64 = terminal_height_f64 / grid_rows_f64;
// Our image width
const width_px = if (self.source_width > 0) self.source_width else image.width;
const height_px = if (self.source_height > 0) self.source_height else image.height;
// Calculate our image size in grid cells
const width_f64: f64 = @floatFromInt(width_px);
const height_f64: f64 = @floatFromInt(height_px);
const width_cells: u32 = @intFromFloat(@ceil(width_f64 / cell_width_f64));
const height_cells: u32 = @intFromFloat(@ceil(height_f64 / cell_height_f64));
return .{
.top_left = self.point,
.bottom_right = .{
.x = @min(self.point.x + width_cells, t.cols - 1),
.y = self.point.y + height_cells,
},
};
}
/// Returns a selection of the entire rectangle this placement /// Returns a selection of the entire rectangle this placement
/// occupies within the screen. /// occupies within the screen.
pub fn selection( pub fn selection(