renderer: clarify and correct custom shader cursor position math

This math was incorrect from the start, the previous fix helped OpenGL
but broke positioning under Metal; this commit fixes the math to be
correct under both backends and adds comments explaining exactly what's
going on.
This commit is contained in:
Qwerasd
2025-08-31 11:43:10 -06:00
parent f7994e6412
commit 0d30f859bd

View File

@@ -2225,23 +2225,46 @@ pub fn Renderer(comptime GraphicsAPI: type) type {
const cursor_width: f32 = @floatFromInt(cursor.glyph_size[0]);
const cursor_height: f32 = @floatFromInt(cursor.glyph_size[1]);
// Left edge of the cell the cursor is in.
var pixel_x: f32 = @floatFromInt(
cursor.grid_pos[0] * cell.width + padding.left,
);
// Top edge, relative to the top of the
// screen, of the cell the cursor is in.
var pixel_y: f32 = @floatFromInt(
cursor.grid_pos[1] * cell.height + padding.top,
);
pixel_x += @floatFromInt(cursor.bearings[0]);
// Convert the Y coordinate from bottom-to-top to top-to-bottom.
// Otherwise we end up with glyphs like underline at the top of the cell.
pixel_y += @floatFromInt(@as(i32, @intCast(cell.height)) - cursor.bearings[1]);
// If +Y is up in our shaders, we need to flip the coordinate.
// If +Y is up in our shaders, we need to flip the coordinate
// so that it's instead the top edge of the cell relative to
// the *bottom* of the screen.
if (!GraphicsAPI.custom_shader_y_is_down) {
pixel_y = @as(f32, @floatFromInt(screen.height)) - pixel_y;
}
// Add the X bearing to get the -X (left) edge of the cursor.
pixel_x += @floatFromInt(cursor.bearings[0]);
// How we deal with the Y bearing depends on which direction
// is "up", since we want our final `pixel_y` value to be the
// +Y edge of the cursor.
if (GraphicsAPI.custom_shader_y_is_down) {
// As a reminder, the Y bearing is the distance from the
// bottom of the cell to the top of the glyph, so to get
// the +Y edge we need to add the cell height, subtract
// the Y bearing, and add the glyph height to get the +Y
// (bottom) edge of the cursor.
pixel_y += @floatFromInt(cell.height);
pixel_y -= @floatFromInt(cursor.bearings[1]);
pixel_y += @floatFromInt(cursor.glyph_size[1]);
} else {
// If the Y direction is reversed though, we instead want
// the *top* edge of the cursor, which means we just need
// to subtract the cell height and add the Y bearing.
pixel_y -= @floatFromInt(cell.height);
pixel_y += @floatFromInt(cursor.bearings[1]);
}
const new_cursor: [4]f32 = .{
pixel_x,
pixel_y,