Merge pull request #2049 from pluiedev/fix/exempt-powerline-from-minimum-contrast

renderer: exempt Powerline cells from minimum contrast requirements
This commit is contained in:
Mitchell Hashimoto
2024-08-06 10:12:14 -07:00
committed by GitHub
8 changed files with 41 additions and 9 deletions

View File

@ -2481,6 +2481,7 @@ fn updateCell(
.normal => .fg,
.color => .fg_color,
.constrained => .fg_constrained,
.powerline => .fg_powerline,
};
try self.cells.add(self.alloc, .text, .{

View File

@ -1253,11 +1253,7 @@ pub fn rebuildCells(
const screen_cell = row.cells(.all)[screen.cursor.x];
const x = screen.cursor.x - @intFromBool(screen_cell.wide == .spacer_tail);
for (self.cells.items[start_i..]) |cell| {
if (cell.grid_col == x and
(cell.mode == .fg or
cell.mode == .fg_color or
cell.mode == .fg_constrained))
{
if (cell.grid_col == x and cell.mode.isFg()) {
cursor_cell = cell;
break;
}
@ -1382,7 +1378,7 @@ pub fn rebuildCells(
_ = try self.addCursor(screen, cursor_style, cursor_color);
if (cursor_cell) |*cell| {
if (cell.mode == .fg or cell.mode == .fg_constrained) {
if (cell.mode.isFg() and cell.mode != .fg_color) {
const cell_color = if (self.cursor_invert) blk: {
const sty = screen.cursor.page_pin.style(screen.cursor.page_cell);
break :blk sty.bg(screen.cursor.page_cell, color_palette) orelse self.background_color;
@ -1708,6 +1704,7 @@ fn updateCell(
.normal => .fg,
.color => .fg_color,
.constrained => .fg_constrained,
.powerline => .fg_powerline,
};
try self.cells.append(self.alloc, .{

View File

@ -14,6 +14,10 @@ pub const FgMode = enum {
/// size. If a glyph is larger than the cell then it must be resized
/// to fit.
constrained,
/// Similar to normal, but the text consists of Powerline glyphs and is
/// optionally exempt from padding color extension and minimum contrast requirements.
powerline,
};
/// Returns the appropriate foreground mode for the given cell. This is
@ -45,10 +49,12 @@ pub fn fgMode(
break :text .normal;
}
// We exempt the Powerline range from this since they exhibit
// box-drawing behavior and should not be constrained.
// Special-case Powerline glyphs. They exhibit box drawing behavior
// and should not be constrained. They have their own special category
// though because they're used for other logic (i.e. disabling
// min contrast).
if (isPowerline(cp)) {
break :text .normal;
break :text .powerline;
}
// If we are at the end of the screen its definitely constrained

View File

@ -319,6 +319,7 @@ pub const CellText = extern struct {
fg_constrained = 2,
fg_color = 3,
cursor = 4,
fg_powerline = 5,
};
};

View File

@ -53,6 +53,7 @@ pub const CellMode = enum(u8) {
fg = 2,
fg_constrained = 3,
fg_color = 7,
fg_powerline = 15,
// Non-exhaustive because masks change it
_,
@ -61,6 +62,17 @@ pub const CellMode = enum(u8) {
pub fn mask(self: CellMode, m: CellMode) CellMode {
return @enumFromInt(@intFromEnum(self) | @intFromEnum(m));
}
pub fn isFg(self: CellMode) bool {
// Since we use bit tricks below, we want to ensure the enum
// doesn't change without us looking at this logic again.
comptime {
const info = @typeInfo(CellMode).Enum;
std.debug.assert(info.fields.len == 5);
}
return @intFromEnum(self) & @intFromEnum(@as(CellMode, .fg)) != 0;
}
};
pub fn init() !CellProgram {

View File

@ -28,6 +28,7 @@ const uint MODE_BG = 1u;
const uint MODE_FG = 2u;
const uint MODE_FG_CONSTRAINED = 3u;
const uint MODE_FG_COLOR = 7u;
const uint MODE_FG_POWERLINE = 15u;
void main() {
float a;
@ -39,6 +40,7 @@ void main() {
case MODE_FG:
case MODE_FG_CONSTRAINED:
case MODE_FG_POWERLINE:
a = texture(text, glyph_tex_coords).r;
vec3 premult = color.rgb * color.a;
out_FragColor = vec4(premult.rgb*a, a);

View File

@ -162,6 +162,7 @@ enum CellTextMode : uint8_t {
MODE_TEXT_CONSTRAINED = 2u,
MODE_TEXT_COLOR = 3u,
MODE_TEXT_CURSOR = 4u,
MODE_TEXT_POWERLINE = 4u,
};
struct CellTextVertexIn {
@ -263,6 +264,10 @@ vertex CellTextVertexOut cell_text_vertex(unsigned int vid [[vertex_id]],
// If we have a minimum contrast, we need to check if we need to
// change the color of the text to ensure it has enough contrast
// with the background.
// We only apply this adjustment to "normal" text with MODE_TEXT,
// since we want color glyphs to appear in their original color
// and Powerline glyphs to be unaffected (else parts of the line would
// have different colors as some parts are displayed via background colors).
if (uniforms.min_contrast > 1.0f && input.mode == MODE_TEXT) {
float4 bg_color = float4(input.bg_color) / 255.0f;
out.color = contrasted_color(uniforms.min_contrast, out.color, bg_color);
@ -288,6 +293,7 @@ fragment float4 cell_text_fragment(CellTextVertexOut in [[stage_in]],
switch (in.mode) {
case MODE_TEXT_CURSOR:
case MODE_TEXT_CONSTRAINED:
case MODE_TEXT_POWERLINE:
case MODE_TEXT: {
// Normalize the texture coordinates to [0,1]
float2 size =

View File

@ -8,6 +8,7 @@ const uint MODE_BG = 1u;
const uint MODE_FG = 2u;
const uint MODE_FG_CONSTRAINED = 3u;
const uint MODE_FG_COLOR = 7u;
const uint MODE_FG_POWERLINE = 15u;
// The grid coordinates (x, y) where x < columns and y < rows
layout (location = 0) in vec2 grid_coord;
@ -198,6 +199,7 @@ void main() {
case MODE_FG:
case MODE_FG_CONSTRAINED:
case MODE_FG_COLOR:
case MODE_FG_POWERLINE:
vec2 glyph_offset_calc = glyph_offset;
// The glyph_offset.y is the y bearing, a y value that when added
@ -227,6 +229,7 @@ void main() {
ivec2 text_size;
switch(mode) {
case MODE_FG_CONSTRAINED:
case MODE_FG_POWERLINE:
case MODE_FG:
text_size = textureSize(text, 0);
break;
@ -242,6 +245,10 @@ void main() {
// If we have a minimum contrast, we need to check if we need to
// change the color of the text to ensure it has enough contrast
// with the background.
// We only apply this adjustment to "normal" text with MODE_FG,
// since we want color glyphs to appear in their original color
// and Powerline glyphs to be unaffected (else parts of the line would
// have different colors as some parts are displayed via background colors).
vec4 color_final = color_in / 255.0;
if (min_contrast > 1.0 && mode == MODE_FG) {
vec4 bg_color = bg_color_in / 255.0;