renderer: convert bg extend to new render state
parent
07115ce9a9
commit
cc268694ed
|
|
@ -15,6 +15,7 @@ const cellpkg = @import("cell.zig");
|
|||
const noMinContrast = cellpkg.noMinContrast;
|
||||
const constraintWidth = cellpkg.constraintWidth;
|
||||
const isCovering = cellpkg.isCovering;
|
||||
const rowNeverExtendBg = @import("row.zig").neverExtendBg;
|
||||
const imagepkg = @import("image.zig");
|
||||
const Image = imagepkg.Image;
|
||||
const ImageMap = imagepkg.ImageMap;
|
||||
|
|
@ -2312,6 +2313,7 @@ pub fn Renderer(comptime GraphicsAPI: type) type {
|
|||
|
||||
// Get our row data from our state
|
||||
const row_data = state.row_data.slice();
|
||||
const row_raws = row_data.items(.raw);
|
||||
const row_cells = row_data.items(.cells);
|
||||
const row_dirty = row_data.items(.dirty);
|
||||
const row_selection = row_data.items(.selection);
|
||||
|
|
@ -2326,10 +2328,11 @@ pub fn Renderer(comptime GraphicsAPI: type) type {
|
|||
);
|
||||
for (
|
||||
0..,
|
||||
row_raws[0..row_len],
|
||||
row_cells[0..row_len],
|
||||
row_dirty[0..row_len],
|
||||
row_selection[0..row_len],
|
||||
) |y_usize, *cells, *dirty, selection| {
|
||||
) |y_usize, row, *cells, *dirty, selection| {
|
||||
const y: terminal.size.CellCountInt = @intCast(y_usize);
|
||||
|
||||
if (!rebuild) {
|
||||
|
|
@ -2343,32 +2346,43 @@ pub fn Renderer(comptime GraphicsAPI: type) type {
|
|||
// Unmark the dirty state in our render state.
|
||||
dirty.* = false;
|
||||
|
||||
// TODO: renderstate
|
||||
// If our viewport is wider than our cell contents buffer,
|
||||
// we still only process cells up to the width of the buffer.
|
||||
const cells_slice = cells.slice();
|
||||
const cells_len = @min(cells_slice.len, self.cells.size.columns);
|
||||
const cells_raw = cells_slice.items(.raw);
|
||||
const cells_style = cells_slice.items(.style);
|
||||
|
||||
// On primary screen, we still apply vertical padding
|
||||
// extension under certain conditions we feel are safe.
|
||||
//
|
||||
// This helps make some scenarios look better while
|
||||
// avoiding scenarios we know do NOT look good.
|
||||
// switch (self.config.padding_color) {
|
||||
// // These already have the correct values set above.
|
||||
// .background, .@"extend-always" => {},
|
||||
//
|
||||
// // Apply heuristics for padding extension.
|
||||
// .extend => if (y == 0) {
|
||||
// self.uniforms.padding_extend.up = !row.neverExtendBg(
|
||||
// color_palette,
|
||||
// background,
|
||||
// );
|
||||
// } else if (y == self.cells.size.rows - 1) {
|
||||
// self.uniforms.padding_extend.down = !row.neverExtendBg(
|
||||
// color_palette,
|
||||
// background,
|
||||
// );
|
||||
// },
|
||||
// }
|
||||
switch (self.config.padding_color) {
|
||||
// These already have the correct values set above.
|
||||
.background, .@"extend-always" => {},
|
||||
|
||||
// Apply heuristics for padding extension.
|
||||
.extend => if (y == 0) {
|
||||
self.uniforms.padding_extend.up = !rowNeverExtendBg(
|
||||
row,
|
||||
cells_raw,
|
||||
cells_style,
|
||||
&state.colors.palette,
|
||||
state.colors.background,
|
||||
);
|
||||
} else if (y == self.cells.size.rows - 1) {
|
||||
self.uniforms.padding_extend.down = !rowNeverExtendBg(
|
||||
row,
|
||||
cells_raw,
|
||||
cells_style,
|
||||
&state.colors.palette,
|
||||
state.colors.background,
|
||||
);
|
||||
},
|
||||
}
|
||||
|
||||
// Iterator of runs for shaping.
|
||||
const cells_slice = cells.slice();
|
||||
var run_iter_opts: font.shape.RunOptions = .{
|
||||
.grid = self.font_grid,
|
||||
.cells = cells_slice,
|
||||
|
|
@ -2393,11 +2407,6 @@ pub fn Renderer(comptime GraphicsAPI: type) type {
|
|||
var shaper_cells: ?[]const font.shape.Cell = null;
|
||||
var shaper_cells_i: usize = 0;
|
||||
|
||||
// If our viewport is wider than our cell contents buffer,
|
||||
// we still only process cells up to the width of the buffer.
|
||||
const cells_len = @min(cells_slice.len, self.cells.size.columns);
|
||||
const cells_raw = cells_slice.items(.raw);
|
||||
const cells_style = cells_slice.items(.style);
|
||||
for (
|
||||
0..,
|
||||
cells_raw[0..cells_len],
|
||||
|
|
|
|||
|
|
@ -0,0 +1,64 @@
|
|||
const std = @import("std");
|
||||
const terminal = @import("../terminal/main.zig");
|
||||
|
||||
// TODO: Test neverExtendBg function
|
||||
|
||||
/// Returns true if the row of this pin should never have its background
|
||||
/// color extended for filling padding space in the renderer. This is
|
||||
/// a set of heuristics that help making our padding look better.
|
||||
pub fn neverExtendBg(
|
||||
row: terminal.page.Row,
|
||||
cells: []const terminal.page.Cell,
|
||||
styles: []const terminal.Style,
|
||||
palette: *const terminal.color.Palette,
|
||||
default_background: terminal.color.RGB,
|
||||
) bool {
|
||||
// Any semantic prompts should not have their background extended
|
||||
// because prompts often contain special formatting (such as
|
||||
// powerline) that looks bad when extended.
|
||||
switch (row.semantic_prompt) {
|
||||
.prompt, .prompt_continuation, .input => return true,
|
||||
.unknown, .command => {},
|
||||
}
|
||||
|
||||
for (0.., cells) |x, *cell| {
|
||||
// If any cell has a default background color then we don't
|
||||
// extend because the default background color probably looks
|
||||
// good enough as an extension.
|
||||
switch (cell.content_tag) {
|
||||
// If it is a background color cell, we check the color.
|
||||
.bg_color_palette, .bg_color_rgb => {
|
||||
const s: terminal.Style = if (cell.hasStyling()) styles[x] else .{};
|
||||
const bg = s.bg(cell, palette) orelse return true;
|
||||
if (bg.eql(default_background)) return true;
|
||||
},
|
||||
|
||||
// If its a codepoint cell we can check the style.
|
||||
.codepoint, .codepoint_grapheme => {
|
||||
// For codepoint containing, we also never extend bg
|
||||
// if any cell has a powerline glyph because these are
|
||||
// perfect-fit.
|
||||
switch (cell.codepoint()) {
|
||||
// Powerline
|
||||
0xE0B0...0xE0C8,
|
||||
0xE0CA,
|
||||
0xE0CC...0xE0D2,
|
||||
0xE0D4,
|
||||
=> return true,
|
||||
|
||||
else => {},
|
||||
}
|
||||
|
||||
// Never extend a cell that has a default background.
|
||||
// A default background is applied if there is no background
|
||||
// on the style or the explicitly set background
|
||||
// matches our default background.
|
||||
const s: terminal.Style = if (cell.hasStyling()) styles[x] else .{};
|
||||
const bg = s.bg(cell, palette) orelse return true;
|
||||
if (bg.eql(default_background)) return true;
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
|
@ -3977,65 +3977,6 @@ pub const Pin = struct {
|
|||
self.rowAndCell().row.dirty = true;
|
||||
}
|
||||
|
||||
/// Returns true if the row of this pin should never have its background
|
||||
/// color extended for filling padding space in the renderer. This is
|
||||
/// a set of heuristics that help making our padding look better.
|
||||
pub fn neverExtendBg(
|
||||
self: Pin,
|
||||
palette: *const color.Palette,
|
||||
default_background: color.RGB,
|
||||
) bool {
|
||||
// Any semantic prompts should not have their background extended
|
||||
// because prompts often contain special formatting (such as
|
||||
// powerline) that looks bad when extended.
|
||||
const rac = self.rowAndCell();
|
||||
switch (rac.row.semantic_prompt) {
|
||||
.prompt, .prompt_continuation, .input => return true,
|
||||
.unknown, .command => {},
|
||||
}
|
||||
|
||||
for (self.cells(.all)) |*cell| {
|
||||
// If any cell has a default background color then we don't
|
||||
// extend because the default background color probably looks
|
||||
// good enough as an extension.
|
||||
switch (cell.content_tag) {
|
||||
// If it is a background color cell, we check the color.
|
||||
.bg_color_palette, .bg_color_rgb => {
|
||||
const s = self.style(cell);
|
||||
const bg = s.bg(cell, palette) orelse return true;
|
||||
if (bg.eql(default_background)) return true;
|
||||
},
|
||||
|
||||
// If its a codepoint cell we can check the style.
|
||||
.codepoint, .codepoint_grapheme => {
|
||||
// For codepoint containing, we also never extend bg
|
||||
// if any cell has a powerline glyph because these are
|
||||
// perfect-fit.
|
||||
switch (cell.codepoint()) {
|
||||
// Powerline
|
||||
0xE0B0...0xE0C8,
|
||||
0xE0CA,
|
||||
0xE0CC...0xE0D2,
|
||||
0xE0D4,
|
||||
=> return true,
|
||||
|
||||
else => {},
|
||||
}
|
||||
|
||||
// Never extend a cell that has a default background.
|
||||
// A default background is applied if there is no background
|
||||
// on the style or the explicitly set background
|
||||
// matches our default background.
|
||||
const s = self.style(cell);
|
||||
const bg = s.bg(cell, palette) orelse return true;
|
||||
if (bg.eql(default_background)) return true;
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/// Iterators. These are the same as PageList iterator funcs but operate
|
||||
/// on pins rather than points. This is MUCH more efficient than calling
|
||||
/// pointFromPin and building up the iterator from points.
|
||||
|
|
|
|||
Loading…
Reference in New Issue