From cfb8108279823c27bc3ac344a1dff76678aa2e1b Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Thu, 22 Jun 2023 16:01:00 -0700 Subject: [PATCH 1/3] font: curly underline has a minimum wave height This fixes rendering issues with some fonts where the underline position is too close to the bottom of the cell causing a very shallow curl. --- src/font/sprite/underline.zig | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/src/font/sprite/underline.zig b/src/font/sprite/underline.zig index abf52236b..b8900e153 100644 --- a/src/font/sprite/underline.zig +++ b/src/font/sprite/underline.zig @@ -24,6 +24,10 @@ pub fn renderGlyph( line_pos: u32, line_thickness: u32, ) !font.Glyph { + // Berkeley: warning: UNDERLINE RENDER width:18 height:37 pos:35 thickness:2 + // Normal: warning: UNDERLINE RENDER width:18 height:38 pos:30 thickness:2 + std.log.warn("UNDERLINE RENDER width:{} height:{} pos:{} thickness:{}", .{ width, height, line_pos, line_thickness }); + // Create the canvas we'll use to draw. We draw the underline in // a full cell size and position it according to "pos". var canvas = try font.sprite.Canvas.init(alloc, width, height); @@ -139,12 +143,21 @@ const Draw = struct { // This is the lowest that the curl can go. const y_max = self.height - 1; + // Some fonts put the underline too close to the bottom of the + // cell height and this doesn't allow us to make a high enough + // 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; + }; + // The full heightof the wave can be from the bottom to the // underline position. We also calculate our starting y which is // slightly below our descender since our wave will move about that. - const wave_height = @intToFloat(f64, y_max - self.pos); + const wave_height = @intToFloat(f64, y_max - pos); const half_height = wave_height / 4; - const y = self.pos + @floatToInt(u32, half_height); + const y = pos + @floatToInt(u32, half_height); const x_factor = (2 * std.math.pi) / @intToFloat(f64, self.width); var x: u32 = 0; From e810a7bf91d1727b69d8c96a6fe33d3d67ea58de Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Thu, 22 Jun 2023 16:07:10 -0700 Subject: [PATCH 2/3] font: fix double underline drawing with very low underline positions --- src/font/sprite/underline.zig | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/src/font/sprite/underline.zig b/src/font/sprite/underline.zig index b8900e153..9fcd5cb11 100644 --- a/src/font/sprite/underline.zig +++ b/src/font/sprite/underline.zig @@ -91,16 +91,26 @@ const Draw = struct { /// Draw a double underline. fn drawDouble(self: Draw, canvas: *font.sprite.Canvas) void { + // The maximum y value has to have space for the bottom underline. + // If we underflow (saturated) to 0, then we don't draw. This should + // never happen but we don't want to draw something undefined. + const y_max = self.height -| 1 -| self.thickness; + if (y_max == 0) return; + + const space = self.thickness * 2; + const bottom = @min(self.pos + space, y_max); + const top = bottom - space; + canvas.rect(.{ .x = 0, - .y = @intCast(i32, self.pos), + .y = @intCast(i32, top), .width = self.width, .height = self.thickness, }, .on); canvas.rect(.{ .x = 0, - .y = @intCast(i32, self.pos + (self.thickness * 2)), + .y = @intCast(i32, bottom), .width = self.width, .height = self.thickness, }, .on); From 43554c1b648114f3aa5fc42589ec250d5f1aa34c Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Thu, 22 Jun 2023 16:07:43 -0700 Subject: [PATCH 3/3] font: remove old logging --- src/font/sprite/underline.zig | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/font/sprite/underline.zig b/src/font/sprite/underline.zig index 9fcd5cb11..532ad0f06 100644 --- a/src/font/sprite/underline.zig +++ b/src/font/sprite/underline.zig @@ -24,10 +24,6 @@ pub fn renderGlyph( line_pos: u32, line_thickness: u32, ) !font.Glyph { - // Berkeley: warning: UNDERLINE RENDER width:18 height:37 pos:35 thickness:2 - // Normal: warning: UNDERLINE RENDER width:18 height:38 pos:30 thickness:2 - std.log.warn("UNDERLINE RENDER width:{} height:{} pos:{} thickness:{}", .{ width, height, line_pos, line_thickness }); - // Create the canvas we'll use to draw. We draw the underline in // a full cell size and position it according to "pos". var canvas = try font.sprite.Canvas.init(alloc, width, height);