From 759c8cddb4f705902762cf8efdbda8522eefc78d Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Sat, 24 Feb 2024 09:30:04 -0800 Subject: [PATCH] font/sprite: test for thick underline, assertion on x/y for rect --- src/font/sprite/canvas.zig | 3 +++ src/font/sprite/underline.zig | 22 +++++++++++++++++++++- 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/src/font/sprite/canvas.zig b/src/font/sprite/canvas.zig index 83d924008..5f869ae98 100644 --- a/src/font/sprite/canvas.zig +++ b/src/font/sprite/canvas.zig @@ -424,6 +424,9 @@ const PixmanImpl = struct { /// Draw and fill a rectangle. This is the main primitive for drawing /// lines as well (which are just generally skinny rectangles...) pub fn rect(self: *Canvas, v: Rect, color: Color) void { + assert(v.x >= 0); + assert(v.y >= 0); + const boxes = &[_]pixman.Box32{ .{ .x1 = @intCast(v.x), diff --git a/src/font/sprite/underline.zig b/src/font/sprite/underline.zig index 163a8fb78..64859b0a6 100644 --- a/src/font/sprite/underline.zig +++ b/src/font/sprite/underline.zig @@ -80,7 +80,7 @@ const Draw = struct { // Ensure we never overflow out of bounds on the canvas const y_max = self.height -| 1; const bottom = @min(self.pos + self.thickness, y_max); - const y = @as(i32, @intCast(bottom)) - @as(i32, @intCast(self.thickness)); + const y = @as(i32, @intCast(bottom -| self.thickness)); canvas.rect(.{ .x = 0, @@ -224,6 +224,26 @@ test "single" { ); } +test "single large thickness" { + const testing = std.testing; + const alloc = testing.allocator; + + var atlas_greyscale = try font.Atlas.init(alloc, 512, .greyscale); + defer atlas_greyscale.deinit(alloc); + + // unrealistic thickness but used to cause a crash + // https://github.com/mitchellh/ghostty/pull/1548 + _ = try renderGlyph( + alloc, + &atlas_greyscale, + .underline, + 36, + 18, + 9, + 200, + ); +} + test "curly" { const testing = std.testing; const alloc = testing.allocator;