diff --git a/src/Window.zig b/src/Window.zig index d03137016..1ea177465 100644 --- a/src/Window.zig +++ b/src/Window.zig @@ -82,6 +82,9 @@ io_thr: std.Thread, /// The dimensions of the grid in rows and columns. grid_size: renderer.GridSize, +/// Explicit padding due to configuration +padding: renderer.Padding, + /// The app configuration config: *const Config, @@ -259,10 +262,21 @@ pub fn create(alloc: Allocator, app: *App, config: *const Config) !*Window { }); errdefer font_group.deinit(alloc); + // Convert our padding from points to pixels + const padding_x = (@intToFloat(f32, config.@"window-padding-x") * x_dpi) / 72; + const padding_y = (@intToFloat(f32, config.@"window-padding-y") * y_dpi) / 72; + const padding: renderer.Padding = .{ + .top = padding_y, + .bottom = padding_y, + .right = padding_x, + .left = padding_x, + }; + // Create our terminal grid with the initial window size var renderer_impl = try Renderer.init(alloc, .{ .font_group = font_group, .padding = .{ + .explicit = padding, .balance = config.@"window-padding-balance", }, }); @@ -284,7 +298,7 @@ pub fn create(alloc: Allocator, app: *App, config: *const Config) !*Window { .width = window_size.width, .height = window_size.height, }; - const grid_size = renderer.GridSize.init(screen_size, renderer_impl.cell_size); + const grid_size = renderer_impl.gridSize(screen_size); // Set a minimum size that is cols=10 h=4. This matches Mac's Terminal.app // but is otherwise somewhat arbitrary. @@ -358,6 +372,7 @@ pub fn create(alloc: Allocator, app: *App, config: *const Config) !*Window { .io_thread = io_thread, .io_thr = undefined, .grid_size = grid_size, + .padding = padding, .config = config, .imgui_ctx = if (!DevMode.enabled) {} else try imgui.Context.create(), @@ -565,13 +580,13 @@ fn sizeCallback(window: glfw.Window, width: i32, height: i32) void { // overhead of inter-thread communication // Recalculate our grid size - win.grid_size.update(screen_size, win.renderer.cell_size); + win.grid_size = win.renderer.gridSize(screen_size); // Mail the IO thread _ = win.io_thread.mailbox.push(.{ .resize = .{ .grid_size = win.grid_size, - .screen_size = screen_size, + .screen_size = screen_size.subPadding(win.padding), }, }, .{ .forever = {} }); win.io_thread.wakeup.send() catch {}; diff --git a/src/cli_args.zig b/src/cli_args.zig index 97bae03c3..4167b6085 100644 --- a/src/cli_args.zig +++ b/src/cli_args.zig @@ -138,6 +138,12 @@ fn parseIntoField( 0, ), + u32 => try std.fmt.parseInt( + u32, + value orelse return error.ValueRequired, + 0, + ), + else => unreachable, }; diff --git a/src/renderer/OpenGL.zig b/src/renderer/OpenGL.zig index fea033d9b..41f025206 100644 --- a/src/renderer/OpenGL.zig +++ b/src/renderer/OpenGL.zig @@ -947,21 +947,34 @@ pub fn updateCell( return true; } +/// Returns the grid size for a given screen size. This is safe to call +/// on any thread. +pub fn gridSize(self: *OpenGL, screen_size: renderer.ScreenSize) renderer.GridSize { + return renderer.GridSize.init( + screen_size.subPadding(self.padding.explicit), + self.cell_size, + ); +} + /// Set the screen size for rendering. This will update the projection /// used for the shader so that the scaling of the grid is correct. fn setScreenSize(self: *OpenGL, dim: renderer.ScreenSize) !void { // Recalculate the rows/columns. - const grid_size = renderer.GridSize.init(dim, self.cell_size); + const grid_size = self.gridSize(dim); - // 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 = if (self.padding.balance) + // Apply our padding + const padding = self.padding.explicit.add(if (self.padding.balance) renderer.Padding.balanced(dim, grid_size, self.cell_size) - else .{}; + else .{}); const padded_dim = dim.subPadding(padding); - log.debug("screen size padded={} screen={} grid={} cell={}", .{ padded_dim, dim, grid_size, self.cell_size }); + log.debug("screen size padded={} screen={} grid={} cell={} padding={}", .{ + padded_dim, + dim, + grid_size, + self.cell_size, + self.padding.explicit, + }); // Update our LRU. We arbitrarily support a certain number of pages here. // We also always support a minimum number of caching in case a user @@ -997,8 +1010,8 @@ fn setScreenSize(self: *OpenGL, dim: renderer.ScreenSize) !void { // 2D orthographic projection with the full w/h math.ortho2d( -1 * padding.left, - @intToFloat(f32, padded_dim.width), - @intToFloat(f32, padded_dim.height), + @intToFloat(f32, padded_dim.width) + padding.right, + @intToFloat(f32, padded_dim.height) + padding.bottom, -1 * padding.top, ), ); diff --git a/src/renderer/Options.zig b/src/renderer/Options.zig index f4e083537..c313d91c6 100644 --- a/src/renderer/Options.zig +++ b/src/renderer/Options.zig @@ -1,6 +1,7 @@ //! The options that are used to configure a renderer. const font = @import("../font/main.zig"); +const renderer = @import("../renderer.zig"); /// The font group that should be used. font_group: *font.GroupCache, @@ -11,10 +12,7 @@ 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, + explicit: renderer.Padding, // Balance options balance: bool = false, diff --git a/src/renderer/size.zig b/src/renderer/size.zig index c59ffb944..51a3b135c 100644 --- a/src/renderer/size.zig +++ b/src/renderer/size.zig @@ -112,6 +112,16 @@ pub const Padding = struct { .left = padding_left, }; } + + /// Add another padding to ths one + pub fn add(self: Padding, other: Padding) Padding { + return .{ + .top = self.top + other.top, + .bottom = self.bottom + other.bottom, + .right = self.right + other.right, + .left = self.left + other.left, + }; + } }; test "GridSize update exact" {