extract auto-padding code to shared logic

This commit is contained in:
Mitchell Hashimoto
2022-11-14 13:10:12 -08:00
parent 024cd65ac8
commit 4cab24a3da
3 changed files with 54 additions and 54 deletions

View File

@ -567,31 +567,8 @@ fn setScreenSize(self: *Metal, bounds: macos.graphics.Size) !void {
// Determine if we need to pad the window. For "auto" padding, we take
// the leftover amounts on the right/bottom that don't fit a full grid cell
// and we split them equal across all boundaries.
// The size of our full grid
const grid_width = @intToFloat(f32, grid_size.columns) * self.cell_size.width;
const grid_height = @intToFloat(f32, grid_size.rows) * self.cell_size.height;
// The empty space to the right of a line and bottom of the last row
const space_right = @intToFloat(f32, dim.width) - grid_width;
const space_bot = @intToFloat(f32, dim.height) - grid_height;
// The left/right padding is just an equal split.
const padding_right = @floatToInt(i32, @floor(space_right / 2));
const padding_left = padding_right;
// The top/bottom padding is interesting. Subjectively, lots of padding
// at the top looks bad. So instead of always being equal (like left/right),
// we force the top padding to be at most equal to the left, and the bottom
// padding is the difference thereafter.
const padding_top = @min(padding_left, @floatToInt(i32, @floor(space_bot / 2)));
const padding_bot = @floatToInt(i32, space_bot - @intToFloat(f32, padding_top));
// The full padded dimensions of the renderable area.
const padded_dim: renderer.ScreenSize = .{
.width = dim.width - @intCast(u32, padding_left + padding_right),
.height = dim.height - @intCast(u32, padding_bot + padding_top),
};
const padding = renderer.Padding.balanced(dim, grid_size, self.cell_size);
const padded_dim = dim.subPadding(padding);
// Update our shaper
// TODO: don't reallocate if it is close enough (but bigger)
@ -607,10 +584,10 @@ fn setScreenSize(self: *Metal, bounds: macos.graphics.Size) !void {
const old = self.uniforms;
self.uniforms = .{
.projection_matrix = math.ortho2d(
@intToFloat(f32, -1 * padding_left),
-1 * padding.left,
@intToFloat(f32, padded_dim.width),
@intToFloat(f32, padded_dim.height),
@intToFloat(f32, -1 * padding_top),
-1 * padding.top,
),
.cell_size = .{ self.cell_size.width, self.cell_size.height },
.underline_position = old.underline_position,

View File

@ -952,31 +952,8 @@ fn setScreenSize(self: *OpenGL, dim: renderer.ScreenSize) !void {
// Determine if we need to pad the window. For "auto" padding, we take
// the leftover amounts on the right/bottom that don't fit a full grid cell
// and we split them equal across all boundaries.
// The size of our full grid
const grid_width = @intToFloat(f32, grid_size.columns) * self.cell_size.width;
const grid_height = @intToFloat(f32, grid_size.rows) * self.cell_size.height;
// The empty space to the right of a line and bottom of the last row
const space_right = @intToFloat(f32, dim.width) - grid_width;
const space_bot = @intToFloat(f32, dim.height) - grid_height;
// The left/right padding is just an equal split.
const padding_right = @floatToInt(i32, @floor(space_right / 2));
const padding_left = padding_right;
// The top/bottom padding is interesting. Subjectively, lots of padding
// at the top looks bad. So instead of always being equal (like left/right),
// we force the top padding to be at most equal to the left, and the bottom
// padding is the difference thereafter.
const padding_top = @min(padding_left, @floatToInt(i32, @floor(space_bot / 2)));
const padding_bot = @floatToInt(i32, space_bot - @intToFloat(f32, padding_top));
// The full padded dimensions of the renderable area.
const padded_dim: renderer.ScreenSize = .{
.width = dim.width - @intCast(u32, padding_left + padding_right),
.height = dim.height - @intCast(u32, padding_bot + padding_top),
};
const padding = renderer.Padding.balanced(dim, grid_size, self.cell_size);
const padded_dim = dim.subPadding(padding);
log.debug("screen size padded={} screen={} grid={} cell={}", .{ padded_dim, dim, grid_size, self.cell_size });
@ -998,8 +975,8 @@ fn setScreenSize(self: *OpenGL, dim: renderer.ScreenSize) !void {
// Update our viewport for this context to be the entire window.
// OpenGL works in pixels, so we have to use the pixel size.
try gl.viewport(
padding_left,
padding_bot,
@floatToInt(i32, padding.left),
@floatToInt(i32, padding.bottom),
@intCast(i32, padded_dim.width),
@intCast(i32, padded_dim.height),
);

View File

@ -44,6 +44,14 @@ pub const CellSize = struct {
pub const ScreenSize = struct {
width: u32,
height: u32,
/// Subtract padding from the screen size.
pub fn subPadding(self: ScreenSize, padding: Padding) ScreenSize {
return .{
.width = self.width - @floatToInt(u32, padding.left + padding.right),
.height = self.height - @floatToInt(u32, padding.top + padding.bottom),
};
}
};
/// The dimensions of the grid itself, in rows/columns units.
@ -68,6 +76,44 @@ pub const GridSize = struct {
}
};
/// The padding to add to a screen.
pub const Padding = struct {
top: f32,
bottom: f32,
right: f32,
left: f32,
/// Returns padding that balances the whitespace around the screen
/// for the given grid and cell sizes.
pub fn balanced(screen: ScreenSize, grid: GridSize, cell: CellSize) Padding {
// The size of our full grid
const grid_width = @intToFloat(f32, grid.columns) * cell.width;
const grid_height = @intToFloat(f32, grid.rows) * cell.height;
// The empty space to the right of a line and bottom of the last row
const space_right = @intToFloat(f32, screen.width) - grid_width;
const space_bot = @intToFloat(f32, screen.height) - grid_height;
// The left/right padding is just an equal split.
const padding_right = @floor(space_right / 2);
const padding_left = padding_right;
// The top/bottom padding is interesting. Subjectively, lots of padding
// at the top looks bad. So instead of always being equal (like left/right),
// we force the top padding to be at most equal to the left, and the bottom
// padding is the difference thereafter.
const padding_top = @min(padding_left, @floor(space_bot / 2));
const padding_bot = space_bot - padding_top;
return .{
.top = padding_top,
.bottom = padding_bot,
.right = padding_right,
.left = padding_left,
};
}
};
test "GridSize update exact" {
const testing = std.testing;