mirror of
https://github.com/kovidgoyal/kitty.git
synced 2026-07-11 02:03:22 +00:00
Backport using uniform for text_fg_override_threshold from slang to legacy glsl
This commit is contained in:
parent
47a238e4b3
commit
5fc2cf4230
9 changed files with 40 additions and 27 deletions
|
|
@ -1,4 +1,3 @@
|
|||
#define FG_OVERRIDE_THRESHOLD {FG_OVERRIDE_THRESHOLD}
|
||||
#define FG_OVERRIDE_ALGO {FG_OVERRIDE_ALGO}
|
||||
#define TEXT_NEW_GAMMA {TEXT_NEW_GAMMA}
|
||||
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@ uniform float gamma_lut[256];
|
|||
uniform uint draw_bg_bitfield;
|
||||
uniform usampler2D sprite_decorations_map;
|
||||
uniform float row_offset;
|
||||
uniform float fg_override_threshold;
|
||||
|
||||
// Have to use fixed locations here as all variants of the cell program share the same VAOs
|
||||
layout(location=0) in uvec3 colors;
|
||||
|
|
@ -268,7 +269,7 @@ vec3 fg_override(float under_luminance, float over_lumininace, vec3 under, vec3
|
|||
// If the difference in luminance is too small,
|
||||
// force the foreground color to be black or white.
|
||||
float diff_luminance = abs(under_luminance - over_lumininace);
|
||||
float override_level = (1.f - colored_sprite) * step(diff_luminance, FG_OVERRIDE_THRESHOLD);
|
||||
float override_level = (1.f - colored_sprite) * step(diff_luminance, fg_override_threshold);
|
||||
float original_level = 1.f - override_level;
|
||||
return original_level * over + override_level * vec3(step(under_luminance, 0.5f));
|
||||
}
|
||||
|
|
@ -279,7 +280,7 @@ vec3 fg_override(float under_luminance, float over_luminance, vec3 under, vec3 o
|
|||
float ratio = contrast_ratio(under_luminance, over_luminance);
|
||||
vec3 diff = abs(under - over);
|
||||
vec3 over_hsluv = rgbToHsluv(over);
|
||||
const float min_contrast_ratio = FG_OVERRIDE_THRESHOLD;
|
||||
const float min_contrast_ratio = fg_override_threshold;
|
||||
float target_lum_a = clamp((under_luminance + 0.05f) * min_contrast_ratio - 0.05f, 0.f, 1.f);
|
||||
float target_lum_b = clamp((under_luminance + 0.05f) / min_contrast_ratio - 0.05f, 0.f, 1.f);
|
||||
vec3 result_a = clamp(hsluvToRgb(vec3(over_hsluv.x, over_hsluv.y, target_lum_a * 100.f)), 0.f, 1.f);
|
||||
|
|
|
|||
|
|
@ -267,7 +267,7 @@ Then adjust the second parameter until it looks good. Then switch to a light the
|
|||
and adjust the first parameter until the perceived thickness matches the dark theme.
|
||||
''')
|
||||
|
||||
opt('text_fg_override_threshold', '0', option_type='text_fg_override_threshold', long_text='''
|
||||
opt('text_fg_override_threshold', '0', option_type='text_fg_override_threshold', ctype='text_fg_override_threshold', long_text='''
|
||||
A setting to prevent low contrast between foreground and background colors.
|
||||
Useful when working with applications that use colors that do not contrast
|
||||
well with your preferred color scheme. The default value is :code:`0`, which means no color overriding is performed.
|
||||
|
|
|
|||
15
kitty/options/to-c-generated.h
generated
15
kitty/options/to-c-generated.h
generated
|
|
@ -122,6 +122,19 @@ convert_from_opts_text_composition_strategy(PyObject *py_opts, Options *opts) {
|
|||
Py_DECREF(ret);
|
||||
}
|
||||
|
||||
static void
|
||||
convert_from_python_text_fg_override_threshold(PyObject *val, Options *opts) {
|
||||
opts->text_fg_override_threshold = text_fg_override_threshold(val);
|
||||
}
|
||||
|
||||
static void
|
||||
convert_from_opts_text_fg_override_threshold(PyObject *py_opts, Options *opts) {
|
||||
PyObject *ret = PyObject_GetAttrString(py_opts, "text_fg_override_threshold");
|
||||
if (ret == NULL) return;
|
||||
convert_from_python_text_fg_override_threshold(ret, opts);
|
||||
Py_DECREF(ret);
|
||||
}
|
||||
|
||||
static void
|
||||
convert_from_python_cursor_shape(PyObject *val, Options *opts) {
|
||||
opts->cursor_shape = PyLong_AsLong(val);
|
||||
|
|
@ -1520,6 +1533,8 @@ convert_opts_from_python_opts(PyObject *py_opts, Options *opts) {
|
|||
if (PyErr_Occurred()) return false;
|
||||
convert_from_opts_text_composition_strategy(py_opts, opts);
|
||||
if (PyErr_Occurred()) return false;
|
||||
convert_from_opts_text_fg_override_threshold(py_opts, opts);
|
||||
if (PyErr_Occurred()) return false;
|
||||
convert_from_opts_cursor_shape(py_opts, opts);
|
||||
if (PyErr_Occurred()) return false;
|
||||
convert_from_opts_cursor_shape_unfocused(py_opts, opts);
|
||||
|
|
|
|||
|
|
@ -45,6 +45,16 @@ parse_ms_long_to_monotonic_t(PyObject *val) {
|
|||
return ms_to_monotonic_t(PyLong_AsUnsignedLong(val));
|
||||
}
|
||||
|
||||
static inline float
|
||||
text_fg_override_threshold(PyObject *val) {
|
||||
double ans = PyFloat_AsDouble(PyTuple_GET_ITEM(val, 0));
|
||||
switch (PyUnicode_AsUTF8(PyTuple_GET_ITEM(val, 1))[0]) {
|
||||
case '%': ans = MAX(0, MIN(ans, 100)) * 0.01; break;
|
||||
default: ans = MAX(0, MIN(ans, 21)); break;
|
||||
}
|
||||
return (float)ans;
|
||||
}
|
||||
|
||||
static inline WindowTitleIn
|
||||
window_title_in(PyObject *title_in) {
|
||||
const char *in = PyUnicode_AsUTF8(title_in);
|
||||
|
|
|
|||
2
kitty/options/types.py
generated
2
kitty/options/types.py
generated
|
|
@ -681,7 +681,7 @@ class Options:
|
|||
tab_separator: str = ' ┇'
|
||||
tab_switch_strategy: choices_for_tab_switch_strategy = 'previous'
|
||||
tab_title_max_length: int = 0
|
||||
tab_title_template: str = '{fmt.fg.red}{bell_symbol}{activity_symbol}{fmt.fg.tab}{tab.last_focused_progress_percent}{title}'
|
||||
tab_title_template: str = '{fmt.fg.red}{bell_symbol}{activity_symbol}{secure_input_symbol}{fmt.fg.tab}{tab.last_focused_progress_percent}{title}'
|
||||
term: str = 'xterm-kitty'
|
||||
terminfo_type: choices_for_terminfo_type = 'path'
|
||||
text_composition_strategy: str = 'platform'
|
||||
|
|
|
|||
|
|
@ -1336,6 +1336,7 @@ call_cell_program(int program, const UIRenderData *ui, ssize_t vao_idx, bool for
|
|||
bind_vao_uniform_buffer(vao_idx, color_table_buffer, COLOR_TABLE_BINDING_POINT);
|
||||
glUniform1ui(cell_program_layouts[program].uniforms.draw_bg_bitfield, draw_bg_bitfield);
|
||||
glUniform1f(cell_program_layouts[program].uniforms.row_offset, row_offset_for_screen(ui->screen));
|
||||
glUniform1f(cell_program_layouts[program].uniforms.fg_override_threshold, OPT(text_fg_override_threshold));
|
||||
if (for_final_output) glEnable(GL_FRAMEBUFFER_SRGB);
|
||||
draw_quad(!for_final_output, render_lines_for_screen(ui->screen) * ui->screen->columns);
|
||||
if (for_final_output) glDisable(GL_FRAMEBUFFER_SRGB);
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ import re
|
|||
from collections.abc import Callable, Iterator
|
||||
from functools import lru_cache, partial
|
||||
from itertools import count
|
||||
from typing import Any, Literal, NamedTuple, Optional
|
||||
from typing import Any, Literal, Optional
|
||||
|
||||
from kitty.constants import read_kitty_resource
|
||||
from kitty.fast_data_types import (
|
||||
|
|
@ -136,14 +136,8 @@ class MultiReplacer:
|
|||
null_replacer = MultiReplacer()
|
||||
|
||||
|
||||
class TextFgOverrideThreshold(NamedTuple):
|
||||
value: float = 0
|
||||
unit: Literal['%', 'ratio'] = '%'
|
||||
scaled_value: float = 0
|
||||
|
||||
|
||||
class LoadShaderPrograms:
|
||||
text_fg_override_threshold: TextFgOverrideThreshold = TextFgOverrideThreshold()
|
||||
text_fg_override_threshold: tuple[float, Literal['%', 'ratio']] = 0, '%'
|
||||
text_old_gamma: bool = False
|
||||
cell_program_replacer: MultiReplacer = null_replacer
|
||||
|
||||
|
|
@ -151,8 +145,9 @@ class LoadShaderPrograms:
|
|||
def needs_recompile(self) -> bool:
|
||||
opts = get_options()
|
||||
return (
|
||||
opts.text_fg_override_threshold != (self.text_fg_override_threshold.value, self.text_fg_override_threshold.unit)
|
||||
or (opts.text_composition_strategy == 'legacy') != self.text_old_gamma
|
||||
bool(opts.text_fg_override_threshold[0]) != bool(self.text_fg_override_threshold[0]) or
|
||||
opts.text_fg_override_threshold[1] != self.text_fg_override_threshold[1] or
|
||||
(opts.text_composition_strategy == 'legacy') != self.text_old_gamma
|
||||
)
|
||||
|
||||
def recompile_if_needed(self) -> None:
|
||||
|
|
@ -162,15 +157,7 @@ class LoadShaderPrograms:
|
|||
def __call__(self, allow_recompile: bool = False) -> None:
|
||||
opts = get_options()
|
||||
self.text_old_gamma = opts.text_composition_strategy == 'legacy'
|
||||
|
||||
text_fg_override_threshold: float = opts.text_fg_override_threshold[0]
|
||||
match opts.text_fg_override_threshold[1]:
|
||||
case '%':
|
||||
text_fg_override_threshold = max(0, min(text_fg_override_threshold, 100.0)) * 0.01
|
||||
case 'ratio':
|
||||
text_fg_override_threshold = max(0, min(text_fg_override_threshold, 21.0))
|
||||
self.text_fg_override_threshold = TextFgOverrideThreshold(
|
||||
opts.text_fg_override_threshold[0], opts.text_fg_override_threshold[1], text_fg_override_threshold)
|
||||
self.text_fg_override_threshold = opts.text_fg_override_threshold
|
||||
|
||||
cell = program_for('cell')
|
||||
if self.cell_program_replacer is null_replacer:
|
||||
|
|
@ -190,14 +177,13 @@ class LoadShaderPrograms:
|
|||
)
|
||||
|
||||
def resolve_cell_defines(only_fg: int, only_bg: int, src: str) -> str:
|
||||
algo = '1' if self.text_fg_override_threshold.unit == '%' else '2'
|
||||
if not self.text_fg_override_threshold.scaled_value:
|
||||
algo = '1' if self.text_fg_override_threshold[1] == '%' else '2'
|
||||
if not self.text_fg_override_threshold[0]:
|
||||
algo = '0'
|
||||
r = self.cell_program_replacer.replacements
|
||||
r['ONLY_FOREGROUND'] = str(only_fg)
|
||||
r['ONLY_BACKGROUND'] = str(only_bg)
|
||||
r['FG_OVERRIDE_ALGO'] = algo
|
||||
r['FG_OVERRIDE_THRESHOLD'] = str(self.text_fg_override_threshold.scaled_value)
|
||||
r['TEXT_NEW_GAMMA'] = '0' if self.text_old_gamma else '1'
|
||||
return self.cell_program_replacer(src)
|
||||
for prog, (only_fg, only_bg) in {
|
||||
|
|
|
|||
|
|
@ -163,6 +163,7 @@ typedef struct Options {
|
|||
double window_drag_tolerance;
|
||||
bool generate_256_palette;
|
||||
int drag_threshold;
|
||||
float text_fg_override_threshold;
|
||||
} Options;
|
||||
|
||||
typedef struct WindowLogoRenderData {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue