initial padding options

This commit is contained in:
Mitchell Hashimoto
2022-11-14 16:19:20 -08:00
parent f169ab3f24
commit c515cb9b5f
6 changed files with 70 additions and 16 deletions

View File

@ -260,7 +260,12 @@ pub fn create(alloc: Allocator, app: *App, config: *const Config) !*Window {
errdefer font_group.deinit(alloc);
// Create our terminal grid with the initial window size
var renderer_impl = try Renderer.init(alloc, font_group);
var renderer_impl = try Renderer.init(alloc, .{
.font_group = font_group,
.padding = .{
.balance = config.@"window-padding-balance",
},
});
errdefer renderer_impl.deinit();
renderer_impl.background = .{
.r = config.background.r,

View File

@ -89,6 +89,27 @@ pub const Config = struct {
///
keybind: Keybinds = .{},
/// Window padding. This applies padding between the terminal cells and
/// the window border. The "x" option applies to the left and right
/// padding and the "y" option is top and bottom. The value is in points,
/// meaning that it will be scaled appropriately for screen DPI.
@"window-padding-x": u32 = 0,
@"window-padding-y": u32 = 0,
/// The viewport dimensions are usually not perfectly divisible by
/// the cell size. In this case, some extra padding on the end of a
/// column and the bottom of the final row may exist. If this is true,
/// then this extra padding is automatically balanced between all four
/// edges to minimize imbalance on one side. If this is false, the top
/// left grid cell will always hug the edge with zero padding other than
/// what may be specified with the other "window-padding" options.
///
/// If other "window-padding" fields are set and this is true, this will
/// still apply. The other padding is applied first and may affect how
/// many grid cells actually exist, and this is applied last in order
/// to balance the padding given a certain viewport size and grid cell size.
@"window-padding-balance": bool = true,
/// Additional configuration files to read.
@"config-file": RepeatableString = .{},

View File

@ -14,6 +14,7 @@ pub usingnamespace @import("renderer/message.zig");
pub usingnamespace @import("renderer/size.zig");
pub const Metal = @import("renderer/Metal.zig");
pub const OpenGL = @import("renderer/OpenGL.zig");
pub const Options = @import("renderer/Options.zig");
pub const Thread = @import("renderer/Thread.zig");
pub const State = @import("renderer/State.zig");

View File

@ -77,6 +77,9 @@ background: terminal.color.RGB,
/// True if the window is focused
focused: bool,
/// Padding options
padding: renderer.Options.Padding,
/// The raw structure that maps directly to the buffer sent to the vertex shader.
/// This must be "extern" so that the field order is not reordered by the
/// Zig compiler.
@ -146,7 +149,7 @@ const GPUCellMode = enum(u8) {
}
};
pub fn init(alloc: Allocator, font_group: *font.GroupCache) !OpenGL {
pub fn init(alloc: Allocator, options: renderer.Options) !OpenGL {
// Create the initial font shaper
var shape_buf = try alloc.alloc(font.Shaper.Cell, 1);
errdefer alloc.free(shape_buf);
@ -157,8 +160,8 @@ pub fn init(alloc: Allocator, font_group: *font.GroupCache) !OpenGL {
// Doesn't matter, any normal ASCII will do we're just trying to make
// sure we use the regular font.
const metrics = metrics: {
const index = (try font_group.indexForCodepoint(alloc, 'M', .regular, .text)).?;
const face = try font_group.group.faceFromIndex(index);
const index = (try options.font_group.indexForCodepoint(alloc, 'M', .regular, .text)).?;
const face = try options.font_group.group.faceFromIndex(index);
break :metrics face.metrics;
};
log.debug("cell dimensions={}", .{metrics});
@ -248,12 +251,12 @@ pub fn init(alloc: Allocator, font_group: *font.GroupCache) !OpenGL {
try texbind.image2D(
0,
.Red,
@intCast(c_int, font_group.atlas_greyscale.size),
@intCast(c_int, font_group.atlas_greyscale.size),
@intCast(c_int, options.font_group.atlas_greyscale.size),
@intCast(c_int, options.font_group.atlas_greyscale.size),
0,
.Red,
.UnsignedByte,
font_group.atlas_greyscale.data.ptr,
options.font_group.atlas_greyscale.data.ptr,
);
}
@ -269,12 +272,12 @@ pub fn init(alloc: Allocator, font_group: *font.GroupCache) !OpenGL {
try texbind.image2D(
0,
.RGBA,
@intCast(c_int, font_group.atlas_color.size),
@intCast(c_int, font_group.atlas_color.size),
@intCast(c_int, options.font_group.atlas_color.size),
@intCast(c_int, options.font_group.atlas_color.size),
0,
.BGRA,
.UnsignedByte,
font_group.atlas_color.data.ptr,
options.font_group.atlas_color.data.ptr,
);
}
@ -289,13 +292,14 @@ pub fn init(alloc: Allocator, font_group: *font.GroupCache) !OpenGL {
.vbo = vbo,
.texture = tex,
.texture_color = tex_color,
.font_group = font_group,
.font_group = options.font_group,
.font_shaper = shaper,
.cursor_visible = true,
.cursor_style = .box,
.background = .{ .r = 0, .g = 0, .b = 0 },
.foreground = .{ .r = 255, .g = 255, .b = 255 },
.focused = true,
.padding = options.padding,
};
}
@ -952,7 +956,9 @@ 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.
const padding = renderer.Padding.balanced(dim, grid_size, self.cell_size);
const padding: renderer.Padding = if (self.padding.balance)
renderer.Padding.balanced(dim, grid_size, self.cell_size)
else .{};
const padded_dim = dim.subPadding(padding);
log.debug("screen size padded={} screen={} grid={} cell={}", .{ padded_dim, dim, grid_size, self.cell_size });

21
src/renderer/Options.zig Normal file
View File

@ -0,0 +1,21 @@
//! The options that are used to configure a renderer.
const font = @import("../font/main.zig");
/// The font group that should be used.
font_group: *font.GroupCache,
/// Padding options for the viewport.
padding: Padding,
pub const Padding = struct {
// Explicit padding options, in pixels. The windowing thread is
// expected to convert points to pixels for a given DPI.
top: u32 = 0,
bottom: u32 = 0,
right: u32 = 0,
left: u32 = 0,
// Balance options
balance: bool = false,
};

View File

@ -78,10 +78,10 @@ pub const GridSize = struct {
/// The padding to add to a screen.
pub const Padding = struct {
top: f32,
bottom: f32,
right: f32,
left: f32,
top: f32 = 0,
bottom: f32 = 0,
right: f32 = 0,
left: f32 = 0,
/// Returns padding that balances the whitespace around the screen
/// for the given grid and cell sizes.