terminal/kitty-gfx: respect display c/r params

This commit is contained in:
Mitchell Hashimoto
2023-08-22 14:43:50 -07:00
parent 3bbfee676b
commit 7ff76ca00d
6 changed files with 48 additions and 1 deletions

View File

@ -748,6 +748,11 @@ fn drawImagePlacement(
@as(f32, @floatFromInt(p.source_width)),
@as(f32, @floatFromInt(p.source_height)),
},
.dest_size = .{
@as(f32, @floatFromInt(p.width)),
@as(f32, @floatFromInt(p.height)),
},
}});
defer buf.deinit();
@ -924,12 +929,18 @@ fn prepKittyGraphics(
else
image.height -| offset_y;
// Calculate the width/height of our image.
const dest_width = if (p.columns > 0) p.columns * self.cell_size.width else source_width;
const dest_height = if (p.rows > 0) p.rows * self.cell_size.height else source_height;
// Accumulate the placement
if (image.width > 0 and image.height > 0) {
try self.image_placements.append(self.alloc, .{
.image_id = kv.key_ptr.image_id,
.x = @intCast(kv.value_ptr.point.x),
.y = @intCast(viewport.y),
.width = dest_width,
.height = dest_height,
.cell_offset_x = kv.value_ptr.x_offset,
.cell_offset_y = kv.value_ptr.y_offset,
.source_x = source_x,

View File

@ -15,6 +15,10 @@ pub const Placement = struct {
x: u32,
y: u32,
/// The width/height of the placed image.
width: u32,
height: u32,
/// The offset in pixels from the top left of the cell. This is
/// clamped to the size of a cell.
cell_offset_x: u32,

View File

@ -62,6 +62,7 @@ pub const Image = extern struct {
grid_pos: [2]f32,
cell_offset: [2]f32,
source_rect: [4]f32,
dest_size: [2]f32,
};
/// The uniforms that are passed to the terminal cell shader.
@ -360,6 +361,17 @@ fn initImagePipeline(device: objc.Object, library: objc.Object) !objc.Object {
attr.setProperty("offset", @as(c_ulong, @offsetOf(Image, "source_rect")));
attr.setProperty("bufferIndex", @as(c_ulong, 0));
}
{
const attr = attrs.msgSend(
objc.Object,
objc.sel("objectAtIndexedSubscript:"),
.{@as(c_ulong, 4)},
);
attr.setProperty("format", @intFromEnum(mtl.MTLVertexFormat.float2));
attr.setProperty("offset", @as(c_ulong, @offsetOf(Image, "dest_size")));
attr.setProperty("bufferIndex", @as(c_ulong, 0));
}
// The layout describes how and when we fetch the next vertex input.
const layouts = objc.Object.fromId(desc.getProperty(?*anyopaque, "layouts"));

View File

@ -201,6 +201,9 @@ struct ImageVertexIn {
// The source rectangle of the texture to sample from.
float4 source_rect [[ attribute(3) ]];
// The final width/height of the image in pixels.
float2 dest_size [[ attribute(4) ]];
};
struct ImageVertexOut {
@ -242,7 +245,7 @@ vertex ImageVertexOut image_vertex(
// The position of our image starts at the top-left of the grid cell and
// adds the source rect width/height components.
float2 image_pos = (uniforms.cell_size * input.grid_pos) + input.cell_offset;
image_pos += input.source_rect.zw * position;
image_pos += input.dest_size * position;
out.position = uniforms.projection_matrix * float4(image_pos.x, image_pos.y, 0.0f, 1.0f);
out.tex_coord = tex_coord;

View File

@ -176,6 +176,8 @@ fn display(
.source_y = d.y,
.source_width = d.width,
.source_height = d.height,
.columns = d.columns,
.rows = d.rows,
};
storage.addPlacement(alloc, img.id, d.placement_id, p) catch |err| {
encodeError(&result, err);

View File

@ -166,6 +166,10 @@ pub const ImageStorage = struct {
source_width: u32 = 0,
source_height: u32 = 0,
/// The columns/rows this image occupies.
columns: u32 = 0,
rows: u32 = 0,
/// Returns a selection of the entire rectangle this placement
/// occupies within the screen.
pub fn selection(
@ -173,6 +177,17 @@ pub const ImageStorage = struct {
image: Image,
t: *const terminal.Terminal,
) terminal.Selection {
// If we have columns/rows specified we can simplify this whole thing.
if (self.columns > 0 and self.rows > 0) {
return terminal.Selection{
.start = self.point,
.end = .{
.x = @min(self.point.x + self.columns, t.cols),
.y = @min(self.point.y + self.rows, t.rows),
},
};
}
// Calculate our cell size.
const terminal_width_f64: f64 = @floatFromInt(t.width_px);
const terminal_height_f64: f64 = @floatFromInt(t.height_px);