mirror of
https://github.com/ghostty-org/ghostty.git
synced 2025-07-14 15:56:13 +03:00
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:
@ -2481,6 +2481,7 @@ fn updateCell(
|
|||||||
.normal => .fg,
|
.normal => .fg,
|
||||||
.color => .fg_color,
|
.color => .fg_color,
|
||||||
.constrained => .fg_constrained,
|
.constrained => .fg_constrained,
|
||||||
|
.powerline => .fg_powerline,
|
||||||
};
|
};
|
||||||
|
|
||||||
try self.cells.add(self.alloc, .text, .{
|
try self.cells.add(self.alloc, .text, .{
|
||||||
|
@ -1253,11 +1253,7 @@ pub fn rebuildCells(
|
|||||||
const screen_cell = row.cells(.all)[screen.cursor.x];
|
const screen_cell = row.cells(.all)[screen.cursor.x];
|
||||||
const x = screen.cursor.x - @intFromBool(screen_cell.wide == .spacer_tail);
|
const x = screen.cursor.x - @intFromBool(screen_cell.wide == .spacer_tail);
|
||||||
for (self.cells.items[start_i..]) |cell| {
|
for (self.cells.items[start_i..]) |cell| {
|
||||||
if (cell.grid_col == x and
|
if (cell.grid_col == x and cell.mode.isFg()) {
|
||||||
(cell.mode == .fg or
|
|
||||||
cell.mode == .fg_color or
|
|
||||||
cell.mode == .fg_constrained))
|
|
||||||
{
|
|
||||||
cursor_cell = cell;
|
cursor_cell = cell;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -1382,7 +1378,7 @@ pub fn rebuildCells(
|
|||||||
|
|
||||||
_ = try self.addCursor(screen, cursor_style, cursor_color);
|
_ = try self.addCursor(screen, cursor_style, cursor_color);
|
||||||
if (cursor_cell) |*cell| {
|
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 cell_color = if (self.cursor_invert) blk: {
|
||||||
const sty = screen.cursor.page_pin.style(screen.cursor.page_cell);
|
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;
|
break :blk sty.bg(screen.cursor.page_cell, color_palette) orelse self.background_color;
|
||||||
@ -1708,6 +1704,7 @@ fn updateCell(
|
|||||||
.normal => .fg,
|
.normal => .fg,
|
||||||
.color => .fg_color,
|
.color => .fg_color,
|
||||||
.constrained => .fg_constrained,
|
.constrained => .fg_constrained,
|
||||||
|
.powerline => .fg_powerline,
|
||||||
};
|
};
|
||||||
|
|
||||||
try self.cells.append(self.alloc, .{
|
try self.cells.append(self.alloc, .{
|
||||||
|
@ -14,6 +14,10 @@ pub const FgMode = enum {
|
|||||||
/// size. If a glyph is larger than the cell then it must be resized
|
/// size. If a glyph is larger than the cell then it must be resized
|
||||||
/// to fit.
|
/// to fit.
|
||||||
constrained,
|
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
|
/// Returns the appropriate foreground mode for the given cell. This is
|
||||||
@ -45,10 +49,12 @@ pub fn fgMode(
|
|||||||
break :text .normal;
|
break :text .normal;
|
||||||
}
|
}
|
||||||
|
|
||||||
// We exempt the Powerline range from this since they exhibit
|
// Special-case Powerline glyphs. They exhibit box drawing behavior
|
||||||
// box-drawing behavior and should not be constrained.
|
// 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)) {
|
if (isPowerline(cp)) {
|
||||||
break :text .normal;
|
break :text .powerline;
|
||||||
}
|
}
|
||||||
|
|
||||||
// If we are at the end of the screen its definitely constrained
|
// If we are at the end of the screen its definitely constrained
|
||||||
|
@ -319,6 +319,7 @@ pub const CellText = extern struct {
|
|||||||
fg_constrained = 2,
|
fg_constrained = 2,
|
||||||
fg_color = 3,
|
fg_color = 3,
|
||||||
cursor = 4,
|
cursor = 4,
|
||||||
|
fg_powerline = 5,
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -53,6 +53,7 @@ pub const CellMode = enum(u8) {
|
|||||||
fg = 2,
|
fg = 2,
|
||||||
fg_constrained = 3,
|
fg_constrained = 3,
|
||||||
fg_color = 7,
|
fg_color = 7,
|
||||||
|
fg_powerline = 15,
|
||||||
|
|
||||||
// Non-exhaustive because masks change it
|
// Non-exhaustive because masks change it
|
||||||
_,
|
_,
|
||||||
@ -61,6 +62,17 @@ pub const CellMode = enum(u8) {
|
|||||||
pub fn mask(self: CellMode, m: CellMode) CellMode {
|
pub fn mask(self: CellMode, m: CellMode) CellMode {
|
||||||
return @enumFromInt(@intFromEnum(self) | @intFromEnum(m));
|
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 {
|
pub fn init() !CellProgram {
|
||||||
|
@ -28,6 +28,7 @@ const uint MODE_BG = 1u;
|
|||||||
const uint MODE_FG = 2u;
|
const uint MODE_FG = 2u;
|
||||||
const uint MODE_FG_CONSTRAINED = 3u;
|
const uint MODE_FG_CONSTRAINED = 3u;
|
||||||
const uint MODE_FG_COLOR = 7u;
|
const uint MODE_FG_COLOR = 7u;
|
||||||
|
const uint MODE_FG_POWERLINE = 15u;
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
float a;
|
float a;
|
||||||
@ -39,6 +40,7 @@ void main() {
|
|||||||
|
|
||||||
case MODE_FG:
|
case MODE_FG:
|
||||||
case MODE_FG_CONSTRAINED:
|
case MODE_FG_CONSTRAINED:
|
||||||
|
case MODE_FG_POWERLINE:
|
||||||
a = texture(text, glyph_tex_coords).r;
|
a = texture(text, glyph_tex_coords).r;
|
||||||
vec3 premult = color.rgb * color.a;
|
vec3 premult = color.rgb * color.a;
|
||||||
out_FragColor = vec4(premult.rgb*a, a);
|
out_FragColor = vec4(premult.rgb*a, a);
|
||||||
|
@ -162,6 +162,7 @@ enum CellTextMode : uint8_t {
|
|||||||
MODE_TEXT_CONSTRAINED = 2u,
|
MODE_TEXT_CONSTRAINED = 2u,
|
||||||
MODE_TEXT_COLOR = 3u,
|
MODE_TEXT_COLOR = 3u,
|
||||||
MODE_TEXT_CURSOR = 4u,
|
MODE_TEXT_CURSOR = 4u,
|
||||||
|
MODE_TEXT_POWERLINE = 4u,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct CellTextVertexIn {
|
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
|
// 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
|
// change the color of the text to ensure it has enough contrast
|
||||||
// with the background.
|
// 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) {
|
if (uniforms.min_contrast > 1.0f && input.mode == MODE_TEXT) {
|
||||||
float4 bg_color = float4(input.bg_color) / 255.0f;
|
float4 bg_color = float4(input.bg_color) / 255.0f;
|
||||||
out.color = contrasted_color(uniforms.min_contrast, out.color, bg_color);
|
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) {
|
switch (in.mode) {
|
||||||
case MODE_TEXT_CURSOR:
|
case MODE_TEXT_CURSOR:
|
||||||
case MODE_TEXT_CONSTRAINED:
|
case MODE_TEXT_CONSTRAINED:
|
||||||
|
case MODE_TEXT_POWERLINE:
|
||||||
case MODE_TEXT: {
|
case MODE_TEXT: {
|
||||||
// Normalize the texture coordinates to [0,1]
|
// Normalize the texture coordinates to [0,1]
|
||||||
float2 size =
|
float2 size =
|
||||||
|
@ -8,6 +8,7 @@ const uint MODE_BG = 1u;
|
|||||||
const uint MODE_FG = 2u;
|
const uint MODE_FG = 2u;
|
||||||
const uint MODE_FG_CONSTRAINED = 3u;
|
const uint MODE_FG_CONSTRAINED = 3u;
|
||||||
const uint MODE_FG_COLOR = 7u;
|
const uint MODE_FG_COLOR = 7u;
|
||||||
|
const uint MODE_FG_POWERLINE = 15u;
|
||||||
|
|
||||||
// The grid coordinates (x, y) where x < columns and y < rows
|
// The grid coordinates (x, y) where x < columns and y < rows
|
||||||
layout (location = 0) in vec2 grid_coord;
|
layout (location = 0) in vec2 grid_coord;
|
||||||
@ -198,6 +199,7 @@ void main() {
|
|||||||
case MODE_FG:
|
case MODE_FG:
|
||||||
case MODE_FG_CONSTRAINED:
|
case MODE_FG_CONSTRAINED:
|
||||||
case MODE_FG_COLOR:
|
case MODE_FG_COLOR:
|
||||||
|
case MODE_FG_POWERLINE:
|
||||||
vec2 glyph_offset_calc = glyph_offset;
|
vec2 glyph_offset_calc = glyph_offset;
|
||||||
|
|
||||||
// The glyph_offset.y is the y bearing, a y value that when added
|
// The glyph_offset.y is the y bearing, a y value that when added
|
||||||
@ -227,6 +229,7 @@ void main() {
|
|||||||
ivec2 text_size;
|
ivec2 text_size;
|
||||||
switch(mode) {
|
switch(mode) {
|
||||||
case MODE_FG_CONSTRAINED:
|
case MODE_FG_CONSTRAINED:
|
||||||
|
case MODE_FG_POWERLINE:
|
||||||
case MODE_FG:
|
case MODE_FG:
|
||||||
text_size = textureSize(text, 0);
|
text_size = textureSize(text, 0);
|
||||||
break;
|
break;
|
||||||
@ -242,6 +245,10 @@ void main() {
|
|||||||
// If we have a minimum contrast, we need to check if we need to
|
// 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
|
// change the color of the text to ensure it has enough contrast
|
||||||
// with the background.
|
// 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;
|
vec4 color_final = color_in / 255.0;
|
||||||
if (min_contrast > 1.0 && mode == MODE_FG) {
|
if (min_contrast > 1.0 && mode == MODE_FG) {
|
||||||
vec4 bg_color = bg_color_in / 255.0;
|
vec4 bg_color = bg_color_in / 255.0;
|
||||||
|
Reference in New Issue
Block a user