mirror of
https://github.com/ghostty-org/ghostty.git
synced 2025-07-14 15:56:13 +03:00
kittygfx: placement with rows (r) param scrolls properly out of viewport
Fixes #2332 Two bugs fixed to fix this behavior: 1. Our destination height didn't account for the top-left being offscreen. 2. We were using the wrong height for the source rectangle. When a rows param (r=) is specified, the image height and destination height are at different scales. We were using the viewport scale for the offset but it should be the image scale.
This commit is contained in:
@ -1821,6 +1821,21 @@ fn prepKittyPlacement(
|
||||
break :offset_y @intCast(offset_pixels);
|
||||
} else 0;
|
||||
|
||||
// If we specify `rows` then our offset above is in viewport space
|
||||
// and not in the coordinate space of the source image. Without `rows`
|
||||
// that's one and the same.
|
||||
const source_offset_y: u32 = if (p.rows > 0) source_offset_y: {
|
||||
// Determine the scale factor to apply for this row height.
|
||||
const image_height: f64 = @floatFromInt(image.height);
|
||||
const viewport_height: f64 = @floatFromInt(p.rows * self.grid_metrics.cell_height);
|
||||
const scale: f64 = image_height / viewport_height;
|
||||
|
||||
// Apply the scale to the offset
|
||||
const offset_y_f64: f64 = @floatFromInt(offset_y);
|
||||
const source_offset_y_f64: f64 = offset_y_f64 * scale;
|
||||
break :source_offset_y @intFromFloat(@round(source_offset_y_f64));
|
||||
} else offset_y;
|
||||
|
||||
// We need to prep this image for upload if it isn't in the cache OR
|
||||
// it is in the cache but the transmit time doesn't match meaning this
|
||||
// image is different.
|
||||
@ -1834,7 +1849,7 @@ fn prepKittyPlacement(
|
||||
|
||||
// Calculate the source rectangle
|
||||
const source_x = @min(image.width, p.source_x);
|
||||
const source_y = @min(image.height, p.source_y + offset_y);
|
||||
const source_y = @min(image.height, p.source_y + source_offset_y);
|
||||
const source_width = if (p.source_width > 0)
|
||||
@min(image.width - source_x, p.source_width)
|
||||
else
|
||||
@ -1846,7 +1861,11 @@ fn prepKittyPlacement(
|
||||
|
||||
// Calculate the width/height of our image.
|
||||
const dest_width = if (p.columns > 0) p.columns * self.grid_metrics.cell_width else source_width;
|
||||
const dest_height = if (p.rows > 0) p.rows * self.grid_metrics.cell_height else source_height;
|
||||
const dest_height = if (p.rows > 0) rows: {
|
||||
// Clip to the viewport to handle scrolling. offset_y is already in
|
||||
// viewport scale so we can subtract it directly.
|
||||
break :rows (p.rows * self.grid_metrics.cell_height) - offset_y;
|
||||
} else source_height;
|
||||
|
||||
// Accumulate the placement
|
||||
if (image.width > 0 and image.height > 0) {
|
||||
|
@ -1052,6 +1052,21 @@ fn prepKittyPlacement(
|
||||
break :offset_y @intCast(offset_pixels);
|
||||
} else 0;
|
||||
|
||||
// If we specify `rows` then our offset above is in viewport space
|
||||
// and not in the coordinate space of the source image. Without `rows`
|
||||
// that's one and the same.
|
||||
const source_offset_y: u32 = if (p.rows > 0) source_offset_y: {
|
||||
// Determine the scale factor to apply for this row height.
|
||||
const image_height: f64 = @floatFromInt(image.height);
|
||||
const viewport_height: f64 = @floatFromInt(p.rows * self.grid_metrics.cell_height);
|
||||
const scale: f64 = image_height / viewport_height;
|
||||
|
||||
// Apply the scale to the offset
|
||||
const offset_y_f64: f64 = @floatFromInt(offset_y);
|
||||
const source_offset_y_f64: f64 = offset_y_f64 * scale;
|
||||
break :source_offset_y @intFromFloat(@round(source_offset_y_f64));
|
||||
} else offset_y;
|
||||
|
||||
// We need to prep this image for upload if it isn't in the cache OR
|
||||
// it is in the cache but the transmit time doesn't match meaning this
|
||||
// image is different.
|
||||
@ -1065,7 +1080,7 @@ fn prepKittyPlacement(
|
||||
|
||||
// Calculate the source rectangle
|
||||
const source_x = @min(image.width, p.source_x);
|
||||
const source_y = @min(image.height, p.source_y + offset_y);
|
||||
const source_y = @min(image.height, p.source_y + source_offset_y);
|
||||
const source_width = if (p.source_width > 0)
|
||||
@min(image.width - source_x, p.source_width)
|
||||
else
|
||||
@ -1077,7 +1092,11 @@ fn prepKittyPlacement(
|
||||
|
||||
// Calculate the width/height of our image.
|
||||
const dest_width = if (p.columns > 0) p.columns * self.grid_metrics.cell_width else source_width;
|
||||
const dest_height = if (p.rows > 0) p.rows * self.grid_metrics.cell_height else source_height;
|
||||
const dest_height = if (p.rows > 0) rows: {
|
||||
// Clip to the viewport to handle scrolling. offset_y is already in
|
||||
// viewport scale so we can subtract it directly.
|
||||
break :rows (p.rows * self.grid_metrics.cell_height) - offset_y;
|
||||
} else source_height;
|
||||
|
||||
// Accumulate the placement
|
||||
if (image.width > 0 and image.height > 0) {
|
||||
|
Reference in New Issue
Block a user