renderer: use fg as extension color for covering glyphs (U+2588)

Fixes #2099

This is another heuristic of sorts to make `window-padding-color=extend`
look better by default. If a fully covering glyph is used then we use
the fg color to extend rather than the background.

This doesn't account for fonts that may do this for whatever codepoints,
but I think that's a special scenario that we should just recommend
disabling this feature.
This commit is contained in:
Mitchell Hashimoto
2024-08-18 11:28:51 -07:00
parent 794f31fb8b
commit 2ee54879a4
3 changed files with 34 additions and 3 deletions

View File

@ -22,6 +22,7 @@ const math = @import("../math.zig");
const Surface = @import("../Surface.zig"); const Surface = @import("../Surface.zig");
const link = @import("link.zig"); const link = @import("link.zig");
const fgMode = @import("cell.zig").fgMode; const fgMode = @import("cell.zig").fgMode;
const isCovering = @import("cell.zig").isCovering;
const shadertoy = @import("shadertoy.zig"); const shadertoy = @import("shadertoy.zig");
const assert = std.debug.assert; const assert = std.debug.assert;
const Allocator = std.mem.Allocator; const Allocator = std.mem.Allocator;
@ -2444,12 +2445,21 @@ fn updateCell(
// the cell is transparent but still copy-able. // the cell is transparent but still copy-able.
const res: BgFg = selection_res orelse cell_res; const res: BgFg = selection_res orelse cell_res;
if (style.flags.invisible) { if (style.flags.invisible) {
break :colors BgFg{ break :colors .{
.bg = res.bg, .bg = res.bg,
.fg = res.bg orelse self.background_color, .fg = res.bg orelse self.background_color,
}; };
} }
// If our cell has a covering glyph, then our bg is set to our fg
// so that padding extension works correctly.
if (!selected and isCovering(cell.codepoint())) {
break :colors .{
.bg = res.fg,
.fg = res.fg,
};
}
break :colors res; break :colors res;
}; };
@ -2489,9 +2499,8 @@ fn updateCell(
self.cells.bgCell(coord.y, coord.x).* = .{ self.cells.bgCell(coord.y, coord.x).* = .{
rgb.r, rgb.g, rgb.b, bg_alpha, rgb.r, rgb.g, rgb.b, bg_alpha,
}; };
if (cell.gridWidth() > 1 and coord.x < self.cells.size.columns - 1) { if (cell.gridWidth() > 1 and coord.x < self.cells.size.columns - 1) {
self.cells.bgCell(coord.y, coord.x).* = .{ self.cells.bgCell(coord.y, coord.x + 1).* = .{
rgb.r, rgb.g, rgb.b, bg_alpha, rgb.r, rgb.g, rgb.b, bg_alpha,
}; };
} }

View File

@ -9,6 +9,7 @@ const testing = std.testing;
const Allocator = std.mem.Allocator; const Allocator = std.mem.Allocator;
const ArenaAllocator = std.heap.ArenaAllocator; const ArenaAllocator = std.heap.ArenaAllocator;
const link = @import("link.zig"); const link = @import("link.zig");
const isCovering = @import("cell.zig").isCovering;
const fgMode = @import("cell.zig").fgMode; const fgMode = @import("cell.zig").fgMode;
const shadertoy = @import("shadertoy.zig"); const shadertoy = @import("shadertoy.zig");
const apprt = @import("../apprt.zig"); const apprt = @import("../apprt.zig");
@ -1649,6 +1650,15 @@ fn updateCell(
}; };
} }
// If our cell has a covering glyph, then our bg is set to our fg
// so that padding extension works correctly.
if (!selected and isCovering(cell.codepoint())) {
break :colors .{
.bg = res.fg,
.fg = res.fg,
};
}
break :colors res; break :colors res;
}; };

View File

@ -2,6 +2,18 @@ const ziglyph = @import("ziglyph");
const font = @import("../font/main.zig"); const font = @import("../font/main.zig");
const terminal = @import("../terminal/main.zig"); const terminal = @import("../terminal/main.zig");
/// Returns true if a codepoint for a cell is a covering character. A covering
/// character is a character that covers the entire cell. This is used to
/// make window-padding-color=extend work better. See #2099.
pub fn isCovering(cp: u21) bool {
return switch (cp) {
// U+2588 FULL BLOCK
0x2588 => true,
else => false,
};
}
pub const FgMode = enum { pub const FgMode = enum {
/// Normal non-colored text rendering. The text can leave the cell /// Normal non-colored text rendering. The text can leave the cell
/// size if it is larger than the cell to allow for ligatures. /// size if it is larger than the cell to allow for ligatures.