diff --git a/src/font/Group.zig b/src/font/Group.zig index ba08ad53f..81ccbc066 100644 --- a/src/font/Group.zig +++ b/src/font/Group.zig @@ -515,6 +515,7 @@ pub fn renderGlyph( alloc, atlas, glyph_index, + opts, ), }; diff --git a/src/font/GroupCache.zig b/src/font/GroupCache.zig index 511ec8137..6e8ee9856 100644 --- a/src/font/GroupCache.zig +++ b/src/font/GroupCache.zig @@ -41,6 +41,7 @@ const CodepointKey = struct { const GlyphKey = struct { index: Group.FontIndex, glyph: u32, + opts: font.face.RenderOptions, }; /// The GroupCache takes ownership of Group and will free it. @@ -124,7 +125,7 @@ pub fn renderGlyph( glyph_index: u32, opts: font.face.RenderOptions, ) !Glyph { - const key: GlyphKey = .{ .index = index, .glyph = glyph_index }; + const key: GlyphKey = .{ .index = index, .glyph = glyph_index, .opts = opts }; const gop = try self.glyphs.getOrPut(alloc, key); // If it is in the cache, use it. diff --git a/src/font/face.zig b/src/font/face.zig index e6dd746b2..2087c864f 100644 --- a/src/font/face.zig +++ b/src/font/face.zig @@ -76,6 +76,10 @@ pub const RenderOptions = struct { /// is typically naive, but ultimately up to the rasterizer. max_height: ?u16 = null, + /// The number of grid cells this glyph will take up. This can be used + /// optionally by the rasterizer to better layout the glyph. + cell_width: ?u2 = null, + /// Thicken the glyph. This draws the glyph with a thicker stroke width. /// This is purely an aesthetic setting. /// diff --git a/src/font/sprite/Face.zig b/src/font/sprite/Face.zig index 3b170b439..1e59adebd 100644 --- a/src/font/sprite/Face.zig +++ b/src/font/sprite/Face.zig @@ -49,6 +49,7 @@ pub fn renderGlyph( alloc: Allocator, atlas: *font.Atlas, cp: u32, + opts: font.face.RenderOptions, ) !font.Glyph { if (std.debug.runtime_safety) { if (!self.hasCodepoint(cp, null)) { @@ -57,11 +58,17 @@ pub fn renderGlyph( } } + // We adjust our sprite width based on the cell width. + const width = switch (opts.cell_width orelse 1) { + 0, 1 => self.width, + else => |width| self.width * width, + }; + // Safe to ".?" because of the above assertion. return switch (Kind.init(cp).?) { .box => box: { const f: Box = .{ - .width = self.width, + .width = width, .height = self.height, .thickness = self.thickness, }; @@ -73,7 +80,7 @@ pub fn renderGlyph( alloc, atlas, @enumFromInt(cp), - self.width, + width, self.height, self.underline_position, self.thickness, diff --git a/src/renderer/Metal.zig b/src/renderer/Metal.zig index 28182f8d1..1b340c6ad 100644 --- a/src/renderer/Metal.zig +++ b/src/renderer/Metal.zig @@ -1364,7 +1364,7 @@ pub fn updateCell( self.alloc, font.sprite_index, @intFromEnum(sprite), - .{}, + .{ .cell_width = if (cell.attrs.wide) 2 else 1 }, ); const color = if (cell.attrs.underline_color) cell.underline_fg else colors.fg; @@ -1421,7 +1421,7 @@ fn addCursor( self.alloc, font.sprite_index, @intFromEnum(sprite), - .{}, + .{ .cell_width = if (cell.attrs.wide) 2 else 1 }, ) catch |err| { log.warn("error rendering cursor glyph err={}", .{err}); return null; diff --git a/src/renderer/OpenGL.zig b/src/renderer/OpenGL.zig index ff4dab542..3ea2cfc30 100644 --- a/src/renderer/OpenGL.zig +++ b/src/renderer/OpenGL.zig @@ -872,7 +872,7 @@ fn addCursor( self.alloc, font.sprite_index, @intFromEnum(sprite), - .{}, + .{ .cell_width = if (cell.attrs.wide) 2 else 1 }, ) catch |err| { log.warn("error rendering cursor glyph err={}", .{err}); return null; @@ -1136,7 +1136,7 @@ pub fn updateCell( self.alloc, font.sprite_index, @intFromEnum(sprite), - .{}, + .{ .cell_width = if (cell.attrs.wide) 2 else 1 }, ); const color = if (cell.attrs.underline_color) cell.underline_fg else colors.fg;