diff --git a/src/Surface.zig b/src/Surface.zig index 5d1a190fa..2d448216e 100644 --- a/src/Surface.zig +++ b/src/Surface.zig @@ -231,6 +231,10 @@ pub fn init( if (config.@"adjust-cell-width") |m| try set.put(alloc, .cell_width, m); if (config.@"adjust-cell-height") |m| try set.put(alloc, .cell_height, m); if (config.@"adjust-font-baseline") |m| try set.put(alloc, .cell_baseline, m); + if (config.@"adjust-underline-position") |m| try set.put(alloc, .underline_position, m); + if (config.@"adjust-underline-thickness") |m| try set.put(alloc, .underline_thickness, m); + if (config.@"adjust-strikethrough-position") |m| try set.put(alloc, .strikethrough_position, m); + if (config.@"adjust-strikethrough-thickness") |m| try set.put(alloc, .strikethrough_thickness, m); break :set set; }; diff --git a/src/config/Config.zig b/src/config/Config.zig index 6701095d0..0088431a7 100644 --- a/src/config/Config.zig +++ b/src/config/Config.zig @@ -138,6 +138,10 @@ const c = @cImport({ @"adjust-cell-width": ?MetricModifier = null, @"adjust-cell-height": ?MetricModifier = null, @"adjust-font-baseline": ?MetricModifier = null, +@"adjust-underline-position": ?MetricModifier = null, +@"adjust-underline-thickness": ?MetricModifier = null, +@"adjust-strikethrough-position": ?MetricModifier = null, +@"adjust-strikethrough-thickness": ?MetricModifier = null, /// Background color for the window. background: Color = .{ .r = 0x28, .g = 0x2C, .b = 0x34 }, diff --git a/src/font/face/Metrics.zig b/src/font/face/Metrics.zig index 82b75c62f..2e7309dc4 100644 --- a/src/font/face/Metrics.zig +++ b/src/font/face/Metrics.zig @@ -26,6 +26,18 @@ pub fn apply(self: *Metrics, mods: ModifierSet) void { var it = mods.iterator(); while (it.next()) |entry| { switch (entry.key_ptr.*) { + // We clamp these values to a minimum of 1 to prevent divide-by-zero + // in downstream operations. + inline .cell_width, + .cell_height, + => |tag| { + const original = @field(self, @tagName(tag)); + @field(self, @tagName(tag)) = @max( + entry.value_ptr.apply(original), + 1, + ); + }, + inline else => |tag| { @field(self, @tagName(tag)) = entry.value_ptr.apply(@field(self, @tagName(tag))); }, diff --git a/src/font/sprite/underline.zig b/src/font/sprite/underline.zig index 8979f2065..5317667e8 100644 --- a/src/font/sprite/underline.zig +++ b/src/font/sprite/underline.zig @@ -171,8 +171,9 @@ const Draw = struct { // wave. This constant is arbitrary, change it for aesthetics. const pos = pos: { const MIN_HEIGHT = 7; - const height = y_max - self.pos; - break :pos if (height < MIN_HEIGHT) self.pos -| MIN_HEIGHT else self.pos; + const clamped_pos = @min(y_max, self.pos); + const height = y_max - clamped_pos; + break :pos if (height < MIN_HEIGHT) clamped_pos -| MIN_HEIGHT else clamped_pos; }; // The full heightof the wave can be from the bottom to the diff --git a/src/renderer/Metal.zig b/src/renderer/Metal.zig index f33553f6b..28182f8d1 100644 --- a/src/renderer/Metal.zig +++ b/src/renderer/Metal.zig @@ -211,7 +211,8 @@ pub fn init(alloc: Allocator, options: renderer.Options) !Metal { options.font_group.group.sprite = font.sprite.Face{ .width = metrics.cell_width, .height = metrics.cell_height, - .thickness = 2 * @as(u32, if (options.config.font_thicken) 2 else 1), + .thickness = metrics.underline_thickness * + @as(u32, if (options.config.font_thicken) 2 else 1), .underline_position = metrics.underline_position, }; diff --git a/src/renderer/OpenGL.zig b/src/renderer/OpenGL.zig index 96b3de5e1..ff4dab542 100644 --- a/src/renderer/OpenGL.zig +++ b/src/renderer/OpenGL.zig @@ -548,7 +548,7 @@ fn resetFontMetrics( font_group.group.sprite = font.sprite.Face{ .width = metrics.cell_width, .height = metrics.cell_height, - .thickness = 2 * @as(u32, if (font_thicken) 2 else 1), + .thickness = metrics.underline_thickness * @as(u32, if (font_thicken) 2 else 1), .underline_position = metrics.underline_position, };