renderer/metal: extend background color of grid border into padding

This commit is contained in:
Mitchell Hashimoto
2024-08-03 15:39:02 -07:00
parent c554b607b7
commit 5309f4d080
4 changed files with 72 additions and 6 deletions

View File

@ -621,6 +621,8 @@ pub fn init(alloc: Allocator, options: renderer.Options) !Metal {
.uniforms = .{ .uniforms = .{
.projection_matrix = undefined, .projection_matrix = undefined,
.cell_size = undefined, .cell_size = undefined,
.grid_size = undefined,
.grid_padding = undefined,
.min_contrast = options.config.min_contrast, .min_contrast = options.config.min_contrast,
.cursor_pos = .{ std.math.maxInt(u16), std.math.maxInt(u16) }, .cursor_pos = .{ std.math.maxInt(u16), std.math.maxInt(u16) },
.cursor_color = undefined, .cursor_color = undefined,
@ -832,7 +834,8 @@ pub fn setFontGrid(self: *Metal, grid: *font.SharedGrid) void {
self.grid_metrics = metrics; self.grid_metrics = metrics;
// Reset our cell contents. // Reset our cell contents.
self.cells.resize(self.alloc, self.gridSize().?) catch |err| { const grid_size = self.gridSize().?;
self.cells.resize(self.alloc, grid_size) catch |err| {
// The setFontGrid function can't fail but resizing our cell // The setFontGrid function can't fail but resizing our cell
// buffer definitely can fail. If it does, our renderer is probably // buffer definitely can fail. If it does, our renderer is probably
// screwed but let's just log it and continue until we can figure // screwed but let's just log it and continue until we can figure
@ -857,6 +860,11 @@ pub fn setFontGrid(self: *Metal, grid: *font.SharedGrid) void {
@floatFromInt(metrics.cell_width), @floatFromInt(metrics.cell_width),
@floatFromInt(metrics.cell_height), @floatFromInt(metrics.cell_height),
}, },
.grid_size = .{
grid_size.columns,
grid_size.rows,
},
.grid_padding = self.uniforms.grid_padding,
.min_contrast = self.uniforms.min_contrast, .min_contrast = self.uniforms.min_contrast,
.cursor_pos = self.uniforms.cursor_pos, .cursor_pos = self.uniforms.cursor_pos,
.cursor_color = self.uniforms.cursor_color, .cursor_color = self.uniforms.cursor_color,
@ -1951,6 +1959,12 @@ pub fn setScreenSize(
self.padding.explicit; self.padding.explicit;
const padded_dim = dim.subPadding(padding); const padded_dim = dim.subPadding(padding);
// Blank space around the grid.
const blank = dim.blankPadding(padding, grid_size, .{
.width = self.grid_metrics.cell_width,
.height = self.grid_metrics.cell_height,
}).add(padding);
// Set the size of the drawable surface to the bounds // Set the size of the drawable surface to the bounds
self.layer.setProperty("drawableSize", macos.graphics.Size{ self.layer.setProperty("drawableSize", macos.graphics.Size{
.width = @floatFromInt(dim.width), .width = @floatFromInt(dim.width),
@ -1970,6 +1984,16 @@ pub fn setScreenSize(
@floatFromInt(self.grid_metrics.cell_width), @floatFromInt(self.grid_metrics.cell_width),
@floatFromInt(self.grid_metrics.cell_height), @floatFromInt(self.grid_metrics.cell_height),
}, },
.grid_size = .{
grid_size.columns,
grid_size.rows,
},
.grid_padding = .{
@floatFromInt(blank.top),
@floatFromInt(blank.right),
@floatFromInt(blank.bottom),
@floatFromInt(blank.left),
},
.min_contrast = old.min_contrast, .min_contrast = old.min_contrast,
.cursor_pos = old.cursor_pos, .cursor_pos = old.cursor_pos,
.cursor_color = old.cursor_color, .cursor_color = old.cursor_color,

View File

@ -106,20 +106,31 @@ pub const Image = extern struct {
/// The uniforms that are passed to the terminal cell shader. /// The uniforms that are passed to the terminal cell shader.
pub const Uniforms = extern struct { pub const Uniforms = extern struct {
// Note: all of the explicit aligmnments are copied from the
// MSL developer reference just so that we can be sure that we got
// it all exactly right.
/// The projection matrix for turning world coordinates to normalized. /// The projection matrix for turning world coordinates to normalized.
/// This is calculated based on the size of the screen. /// This is calculated based on the size of the screen.
projection_matrix: math.Mat, projection_matrix: math.Mat align(16),
/// Size of a single cell in pixels, unscaled. /// Size of a single cell in pixels, unscaled.
cell_size: [2]f32, cell_size: [2]f32 align(8),
/// Size of the grid in columns and rows.
grid_size: [2]u16 align(4),
/// The padding around the terminal grid in pixels. In order:
/// top, right, bottom, left.
grid_padding: [4]f32 align(16),
/// The minimum contrast ratio for text. The contrast ratio is calculated /// The minimum contrast ratio for text. The contrast ratio is calculated
/// according to the WCAG 2.0 spec. /// according to the WCAG 2.0 spec.
min_contrast: f32, min_contrast: f32 align(4),
/// The cursor position and color. /// The cursor position and color.
cursor_pos: [2]u16, cursor_pos: [2]u16 align(4),
cursor_color: [4]u8, cursor_color: [4]u8 align(4),
}; };
/// The uniforms used for custom postprocess shaders. /// The uniforms used for custom postprocess shaders.

View File

@ -3,6 +3,8 @@ using namespace metal;
struct Uniforms { struct Uniforms {
float4x4 projection_matrix; float4x4 projection_matrix;
float2 cell_size; float2 cell_size;
ushort2 grid_size;
float4 grid_padding;
float min_contrast; float min_contrast;
ushort2 cursor_pos; ushort2 cursor_pos;
uchar4 cursor_color; uchar4 cursor_color;
@ -98,6 +100,16 @@ vertex CellBgVertexOut cell_bg_vertex(unsigned int vid [[vertex_id]],
float2 cell_size_scaled = uniforms.cell_size; float2 cell_size_scaled = uniforms.cell_size;
cell_size_scaled.x = cell_size_scaled.x * input.cell_width; cell_size_scaled.x = cell_size_scaled.x * input.cell_width;
// If we're at the edge of the grid, we add our padding to the background
// to extend it. Note: grid_padding is top/right/bottom/left.
// TODO: top/left
if (input.grid_pos.y == uniforms.grid_size.y - 1) {
cell_size_scaled.y += uniforms.grid_padding.b;
}
if (input.grid_pos.x == uniforms.grid_size.x - 1) {
cell_size_scaled.x += uniforms.grid_padding.g;
}
// Turn the cell position into a vertex point depending on the // Turn the cell position into a vertex point depending on the
// vertex ID. Since we use instanced drawing, we have 4 vertices // vertex ID. Since we use instanced drawing, we have 4 vertices
// for each corner of the cell. We can use vertex ID to determine // for each corner of the cell. We can use vertex ID to determine

View File

@ -34,6 +34,25 @@ pub const ScreenSize = struct {
}; };
} }
/// Calculates the amount of blank space around the grid. This is possible
/// when padding isn't balanced.
///
/// The "self" screen size here should be the unpadded screen.
pub fn blankPadding(self: ScreenSize, padding: Padding, grid: GridSize, cell: CellSize) Padding {
const grid_width = grid.columns * cell.width;
const grid_height = grid.rows * cell.height;
const padded_width = grid_width + (padding.left + padding.right);
const padded_height = grid_height + (padding.top + padding.bottom);
const leftover_width = self.width - padded_width;
const leftover_height = self.height - padded_height;
return .{
.top = 0,
.bottom = leftover_height,
.right = leftover_width,
.left = 0,
};
}
/// Returns true if two sizes are equal. /// Returns true if two sizes are equal.
pub fn equals(self: ScreenSize, other: ScreenSize) bool { pub fn equals(self: ScreenSize, other: ScreenSize) bool {
return self.width == other.width and self.height == other.height; return self.width == other.width and self.height == other.height;