mirror of
https://github.com/ghostty-org/ghostty.git
synced 2025-10-14 05:46:17 +00:00
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:
@@ -2225,23 +2225,46 @@ pub fn Renderer(comptime GraphicsAPI: type) type {
|
|||||||
const cursor_width: f32 = @floatFromInt(cursor.glyph_size[0]);
|
const cursor_width: f32 = @floatFromInt(cursor.glyph_size[0]);
|
||||||
const cursor_height: f32 = @floatFromInt(cursor.glyph_size[1]);
|
const cursor_height: f32 = @floatFromInt(cursor.glyph_size[1]);
|
||||||
|
|
||||||
|
// Left edge of the cell the cursor is in.
|
||||||
var pixel_x: f32 = @floatFromInt(
|
var pixel_x: f32 = @floatFromInt(
|
||||||
cursor.grid_pos[0] * cell.width + padding.left,
|
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(
|
var pixel_y: f32 = @floatFromInt(
|
||||||
cursor.grid_pos[1] * cell.height + padding.top,
|
cursor.grid_pos[1] * cell.height + padding.top,
|
||||||
);
|
);
|
||||||
|
|
||||||
pixel_x += @floatFromInt(cursor.bearings[0]);
|
// If +Y is up in our shaders, we need to flip the coordinate
|
||||||
// Convert the Y coordinate from bottom-to-top to top-to-bottom.
|
// so that it's instead the top edge of the cell relative to
|
||||||
// Otherwise we end up with glyphs like underline at the top of the cell.
|
// the *bottom* of the screen.
|
||||||
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 (!GraphicsAPI.custom_shader_y_is_down) {
|
if (!GraphicsAPI.custom_shader_y_is_down) {
|
||||||
pixel_y = @as(f32, @floatFromInt(screen.height)) - pixel_y;
|
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 = .{
|
const new_cursor: [4]f32 = .{
|
||||||
pixel_x,
|
pixel_x,
|
||||||
pixel_y,
|
pixel_y,
|
||||||
|
Reference in New Issue
Block a user