renderer/metal: honor cell offset graphics command

This commit is contained in:
Mitchell Hashimoto
2023-08-22 13:28:40 -07:00
parent e6155b7f19
commit 84c72bbe46
6 changed files with 39 additions and 3 deletions

View File

@ -737,6 +737,11 @@ fn drawImagePlacement(
@as(f32, @floatFromInt(p.y)), @as(f32, @floatFromInt(p.y)),
}, },
.cell_offset = .{
@as(f32, @floatFromInt(p.cell_offset_x)),
@as(f32, @floatFromInt(p.cell_offset_y)),
},
.offset_y = p.offset_y, .offset_y = p.offset_y,
}}); }});
defer buf.deinit(); defer buf.deinit();
@ -929,6 +934,8 @@ fn prepKittyGraphics(
.image_id = kv.key_ptr.image_id, .image_id = kv.key_ptr.image_id,
.x = @intCast(kv.value_ptr.point.x), .x = @intCast(kv.value_ptr.point.x),
.y = @intCast(viewport.y), .y = @intCast(viewport.y),
.cell_offset_x = kv.value_ptr.x_offset,
.cell_offset_y = kv.value_ptr.y_offset,
.offset_y = offset_y, .offset_y = offset_y,
}); });
} }

View File

@ -15,6 +15,11 @@ pub const Placement = struct {
x: u32, x: u32,
y: u32, y: 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,
cell_offset_y: u32,
/// The offset of the top of the image texture in case we are clipping /// The offset of the top of the image texture in case we are clipping
/// the top. We don't need an offset_x because we don't support any /// the top. We don't need an offset_x because we don't support any
/// horizontal scrolling so the width is never clipped from the left. /// horizontal scrolling so the width is never clipped from the left.

View File

@ -60,6 +60,7 @@ pub const Cell = extern struct {
/// Single parameter for the image shader. See shader for field details. /// Single parameter for the image shader. See shader for field details.
pub const Image = extern struct { pub const Image = extern struct {
grid_pos: [2]f32, grid_pos: [2]f32,
cell_offset: [2]f32,
offset_y: u32, offset_y: u32,
}; };
@ -344,6 +345,17 @@ fn initImagePipeline(device: objc.Object, library: objc.Object) !objc.Object {
.{@as(c_ulong, 2)}, .{@as(c_ulong, 2)},
); );
attr.setProperty("format", @intFromEnum(mtl.MTLVertexFormat.float2));
attr.setProperty("offset", @as(c_ulong, @offsetOf(Image, "cell_offset")));
attr.setProperty("bufferIndex", @as(c_ulong, 0));
}
{
const attr = attrs.msgSend(
objc.Object,
objc.sel("objectAtIndexedSubscript:"),
.{@as(c_ulong, 3)},
);
attr.setProperty("format", @intFromEnum(mtl.MTLVertexFormat.uint)); attr.setProperty("format", @intFromEnum(mtl.MTLVertexFormat.uint));
attr.setProperty("offset", @as(c_ulong, @offsetOf(Image, "offset_y"))); attr.setProperty("offset", @as(c_ulong, @offsetOf(Image, "offset_y")));
attr.setProperty("bufferIndex", @as(c_ulong, 0)); attr.setProperty("bufferIndex", @as(c_ulong, 0));

View File

@ -195,8 +195,12 @@ struct ImageVertexIn {
// the image will be rendered. It will be rendered from the top left. // the image will be rendered. It will be rendered from the top left.
float2 grid_pos [[ attribute(1) ]]; float2 grid_pos [[ attribute(1) ]];
// Offset in pixels from the top-left of the cell to make the top-left
// corner of the image.
float2 cell_offset [[ attribute(2) ]];
// The offset for the texture coordinates. // The offset for the texture coordinates.
uint offset_y [[ attribute(2) ]]; uint offset_y [[ attribute(3) ]];
}; };
struct ImageVertexOut { struct ImageVertexOut {
@ -235,7 +239,7 @@ vertex ImageVertexOut image_vertex(
ImageVertexOut out; ImageVertexOut out;
// The position of our image starts at the top-left of the grid cell. // The position of our image starts at the top-left of the grid cell.
float2 image_pos = uniforms.cell_size * input.grid_pos; float2 image_pos = (uniforms.cell_size * input.grid_pos) + input.cell_offset;
// We need to adjust the bottom y of the image by offset y otherwise // We need to adjust the bottom y of the image by offset y otherwise
// as we scroll the full image will be rendered and stretched. // as we scroll the full image will be rendered and stretched.

View File

@ -168,7 +168,11 @@ fn display(
}).toScreen(&terminal.screen); }).toScreen(&terminal.screen);
// Add the placement // Add the placement
const p: ImageStorage.Placement = .{ .point = placement_point }; const p: ImageStorage.Placement = .{
.point = placement_point,
.x_offset = d.x_offset,
.y_offset = d.y_offset,
};
storage.addPlacement(alloc, img.id, d.placement_id, p) catch |err| { storage.addPlacement(alloc, img.id, d.placement_id, p) catch |err| {
encodeError(&result, err); encodeError(&result, err);
return result; return result;

View File

@ -156,6 +156,10 @@ pub const ImageStorage = struct {
/// The location of the image on the screen. /// The location of the image on the screen.
point: ScreenPoint, point: ScreenPoint,
/// Offset of the x/y from the top-left of the cell.
x_offset: u32 = 0,
y_offset: u32 = 0,
/// 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(