Merge branch 'linear-gamma-blending' of https://github.com/m4rw3r/kitty
This commit is contained in:
commit
b5b070aade
48
gen-srgb-lut.py
Executable file
48
gen-srgb-lut.py
Executable file
@ -0,0 +1,48 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
# vim:fileencoding=utf-8
|
||||||
|
|
||||||
|
import os
|
||||||
|
from typing import List
|
||||||
|
|
||||||
|
|
||||||
|
def to_linear(a: float) -> float:
|
||||||
|
if a <= 0.04045:
|
||||||
|
return a / 12.92
|
||||||
|
else:
|
||||||
|
return float(pow((a + 0.055) / 1.055, 2.4))
|
||||||
|
|
||||||
|
|
||||||
|
def generate_srgb_lut(line_prefix: str = '') -> List[str]:
|
||||||
|
values: List[str] = []
|
||||||
|
lines: List[str] = []
|
||||||
|
|
||||||
|
for i in range(256):
|
||||||
|
values.append('{:1.5f}f'.format(to_linear(i / 255.0)))
|
||||||
|
|
||||||
|
for i in range(16):
|
||||||
|
lines.append(line_prefix + ', '.join(values[i * 16:(i + 1) * 16]) + ',')
|
||||||
|
|
||||||
|
return lines
|
||||||
|
|
||||||
|
|
||||||
|
def generate_srgb_gamma_c() -> str:
|
||||||
|
lines: List[str] = []
|
||||||
|
|
||||||
|
lines.append('// Generated by gen-srgb-lut.py DO NOT edit')
|
||||||
|
lines.append('#include "srgb_gamma.h"')
|
||||||
|
lines.append('')
|
||||||
|
lines.append('const GLfloat srgb_lut[256] = {')
|
||||||
|
lines += generate_srgb_lut(' ')
|
||||||
|
lines.append('};')
|
||||||
|
|
||||||
|
return "\n".join(lines)
|
||||||
|
|
||||||
|
|
||||||
|
def main() -> None:
|
||||||
|
c = generate_srgb_gamma_c()
|
||||||
|
with open(os.path.join('kitty', 'srgb_gamma.c'), 'w') as f:
|
||||||
|
f.write(f'{c}\n')
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
main()
|
||||||
@ -3,6 +3,7 @@ uniform uvec2 viewport;
|
|||||||
uniform uint colors[9];
|
uniform uint colors[9];
|
||||||
uniform float background_opacity;
|
uniform float background_opacity;
|
||||||
uniform float tint_opacity, tint_premult;
|
uniform float tint_opacity, tint_premult;
|
||||||
|
uniform float gamma_lut[256];
|
||||||
in vec4 rect; // left, top, right, bottom
|
in vec4 rect; // left, top, right, bottom
|
||||||
in uint rect_color;
|
in uint rect_color;
|
||||||
out vec4 color;
|
out vec4 color;
|
||||||
@ -22,7 +23,7 @@ const uvec2 pos_map[] = uvec2[4](
|
|||||||
);
|
);
|
||||||
|
|
||||||
float to_color(uint c) {
|
float to_color(uint c) {
|
||||||
return float(c & FF) / 255.0;
|
return gamma_lut[c & FF];
|
||||||
}
|
}
|
||||||
|
|
||||||
float is_integer_value(uint c, float x) {
|
float is_integer_value(uint c, float x) {
|
||||||
|
|||||||
@ -20,6 +20,9 @@ in float bg_alpha;
|
|||||||
|
|
||||||
#ifdef NEEDS_FOREGROUND
|
#ifdef NEEDS_FOREGROUND
|
||||||
uniform sampler2DArray sprites;
|
uniform sampler2DArray sprites;
|
||||||
|
uniform int text_old_gamma;
|
||||||
|
uniform float text_contrast;
|
||||||
|
uniform float text_gamma_adjustment;
|
||||||
in float effective_text_alpha;
|
in float effective_text_alpha;
|
||||||
in vec3 sprite_pos;
|
in vec3 sprite_pos;
|
||||||
in vec3 underline_pos;
|
in vec3 underline_pos;
|
||||||
@ -34,32 +37,36 @@ in float colored_sprite;
|
|||||||
out vec4 final_color;
|
out vec4 final_color;
|
||||||
|
|
||||||
// Util functions {{{
|
// Util functions {{{
|
||||||
vec4 alpha_blend(vec3 over, float over_alpha, vec3 under, float under_alpha) {
|
vec4 alpha_blend(vec4 over, vec4 under) {
|
||||||
// Alpha blend two colors returning the resulting color pre-multiplied by its alpha
|
// Alpha blend two colors returning the resulting color pre-multiplied by its alpha
|
||||||
// and its alpha.
|
// and its alpha.
|
||||||
// See https://en.wikipedia.org/wiki/Alpha_compositing
|
// See https://en.wikipedia.org/wiki/Alpha_compositing
|
||||||
float alpha = mix(under_alpha, 1.0f, over_alpha);
|
float alpha = mix(under.a, 1.0f, over.a);
|
||||||
vec3 combined_color = mix(under * under_alpha, over, over_alpha);
|
vec3 combined_color = mix(under.rgb * under.a, over.rgb, over.a);
|
||||||
return vec4(combined_color, alpha);
|
return vec4(combined_color, alpha);
|
||||||
}
|
}
|
||||||
|
|
||||||
vec3 premul_blend(vec3 over, float over_alpha, vec3 under) {
|
vec4 alpha_blend_premul(vec4 over, vec4 under) {
|
||||||
return over + (1.0f - over_alpha) * under;
|
|
||||||
}
|
|
||||||
|
|
||||||
vec4 alpha_blend_premul(vec3 over, float over_alpha, vec3 under, float under_alpha) {
|
|
||||||
// Same as alpha_blend() except that it assumes over and under are both premultiplied.
|
// Same as alpha_blend() except that it assumes over and under are both premultiplied.
|
||||||
float alpha = mix(under_alpha, 1.0f, over_alpha);
|
float inv_over_alpha = 1.0f - over.a;
|
||||||
return vec4(premul_blend(over, over_alpha, under), alpha);
|
float alpha = over.a + under.a * inv_over_alpha;
|
||||||
|
return vec4(over.rgb + under.rgb * inv_over_alpha, alpha);
|
||||||
}
|
}
|
||||||
|
|
||||||
vec4 blend_onto_opaque_premul(vec3 over, float over_alpha, vec3 under) {
|
vec4 alpha_blend_premul(vec4 over, vec3 under) {
|
||||||
// same as alpha_blend_premul with under_alpha = 1 outputs a blended color
|
// same as alpha_blend_premul with under_alpha = 1 outputs a blended color
|
||||||
// with alpha 1 which is effectively pre-multiplied since alpha is 1
|
// with alpha 1 which is effectively pre-multiplied since alpha is 1
|
||||||
return vec4(premul_blend(over, over_alpha, under), 1.0);
|
float inv_over_alpha = 1.0f - over.a;
|
||||||
|
return vec4(over.rgb + under.rgb * inv_over_alpha, 1.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
vec4 vec4_premul(vec3 rgb, float a) {
|
||||||
|
return vec4(rgb * a, a);
|
||||||
|
}
|
||||||
|
|
||||||
|
vec4 vec4_premul(vec4 rgba) {
|
||||||
|
return vec4(rgba.rgb * rgba.a, rgba.a);
|
||||||
|
}
|
||||||
// }}}
|
// }}}
|
||||||
|
|
||||||
|
|
||||||
@ -94,45 +101,101 @@ vec4 blend_onto_opaque_premul(vec3 over, float over_alpha, vec3 under) {
|
|||||||
* to the appropriate rendering pass from above.
|
* to the appropriate rendering pass from above.
|
||||||
*/
|
*/
|
||||||
#ifdef NEEDS_FOREGROUND
|
#ifdef NEEDS_FOREGROUND
|
||||||
vec4 calculate_foreground() {
|
// sRGB luminance values
|
||||||
// returns the effective foreground color in pre-multiplied form
|
const vec3 Y = vec3(0.2126, 0.7152, 0.0722);
|
||||||
|
// Scaling factor for the extra text-alpha adjustment for luminance-difference.
|
||||||
|
const float text_gamma_scaling = 0.5;
|
||||||
|
|
||||||
|
float linear2srgb(float x) {
|
||||||
|
// Approximation of linear-to-sRGB conversion
|
||||||
|
return pow(x, 1.0 / 2.2);
|
||||||
|
}
|
||||||
|
|
||||||
|
float srgb2linear(float x) {
|
||||||
|
// Approximation of sRGB-to-linear conversion
|
||||||
|
return pow(x, 2.2);
|
||||||
|
}
|
||||||
|
|
||||||
|
float clamp(float x) {
|
||||||
|
// Clamp value to suitable output range
|
||||||
|
return max(min(x, 1.0f), 0.0f);
|
||||||
|
}
|
||||||
|
|
||||||
|
vec4 foreground_contrast(vec4 over, vec3 under) {
|
||||||
|
float underL = dot(under, Y);
|
||||||
|
float overL = dot(over.rgb, Y);
|
||||||
|
// Apply additional gamma-adjustment scaled by the luminance difference, the darker the foreground the more adjustment we apply.
|
||||||
|
// A multiplicative contrast is also available to increase sasturation.
|
||||||
|
over.a = clamp(mix(over.a, pow(over.a, text_gamma_adjustment), (1 - overL + underL) * text_gamma_scaling) * text_contrast);
|
||||||
|
return over;
|
||||||
|
}
|
||||||
|
|
||||||
|
vec4 foreground_contrast_incorrect(vec4 over, vec3 under) {
|
||||||
|
// Simulation of gamma-incorrect blending
|
||||||
|
float underL = dot(under, Y);
|
||||||
|
float overL = dot(over.rgb, Y);
|
||||||
|
// This is the original gamma-incorrect rendering, it is the solution of the following equation:
|
||||||
|
//
|
||||||
|
// linear2srgb(over * overA2 + under * (1 - overA2)) = linear2srgb(over) * over.a + linear2srgb(under) * (1 - over.a)
|
||||||
|
// ^ gamma correct blending with new alpha ^ gamma incorrect blending with old alpha
|
||||||
|
over.a = clamp((srgb2linear(linear2srgb(overL) * over.a + linear2srgb(underL) * (1.0f - over.a)) - underL) / (overL - underL));
|
||||||
|
return over;
|
||||||
|
}
|
||||||
|
|
||||||
|
vec4 foreground_color() {
|
||||||
vec4 text_fg = texture(sprites, sprite_pos);
|
vec4 text_fg = texture(sprites, sprite_pos);
|
||||||
vec3 fg = mix(foreground, text_fg.rgb, colored_sprite);
|
return vec4(mix(foreground, text_fg.rgb, colored_sprite), text_fg.a);
|
||||||
float text_alpha = text_fg.a;
|
}
|
||||||
|
|
||||||
|
vec4 foreground_with_decorations(vec4 text_fg) {
|
||||||
float underline_alpha = texture(sprites, underline_pos).a;
|
float underline_alpha = texture(sprites, underline_pos).a;
|
||||||
float strike_alpha = texture(sprites, strike_pos).a;
|
float strike_alpha = texture(sprites, strike_pos).a;
|
||||||
float cursor_alpha = texture(sprites, cursor_pos).a;
|
float cursor_alpha = texture(sprites, cursor_pos).a;
|
||||||
// Since strike and text are the same color, we simply add the alpha values
|
// Since strike and text are the same color, we simply add the alpha values
|
||||||
float combined_alpha = min(text_alpha + strike_alpha, 1.0f);
|
float combined_alpha = min(text_fg.a + strike_alpha, 1.0f);
|
||||||
// Underline color might be different, so alpha blend
|
// Underline color might be different, so alpha blend
|
||||||
vec4 ans = alpha_blend(fg, combined_alpha * effective_text_alpha, decoration_fg, underline_alpha * effective_text_alpha);
|
vec4 ans = alpha_blend(vec4(text_fg.rgb, combined_alpha * effective_text_alpha), vec4(decoration_fg, underline_alpha * effective_text_alpha));
|
||||||
return mix(ans, cursor_color_vec, cursor_alpha);
|
return mix(ans, cursor_color_vec, cursor_alpha);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
vec4 calculate_foreground() {
|
||||||
|
// returns the effective foreground color in pre-multiplied form
|
||||||
|
vec4 text_fg = foreground_color();
|
||||||
|
return foreground_with_decorations(text_fg);
|
||||||
|
}
|
||||||
|
vec4 calculate_foreground(vec3 bg) {
|
||||||
|
// When rendering on a background we can adjust the alpha channel contrast
|
||||||
|
// to improve legibility based on the source and destination colors
|
||||||
|
vec4 text_fg = foreground_color();
|
||||||
|
text_fg = mix(foreground_contrast(text_fg, bg), foreground_contrast_incorrect(text_fg, bg), text_old_gamma);
|
||||||
|
return foreground_with_decorations(text_fg);
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
#ifdef SIMPLE
|
#ifdef SIMPLE
|
||||||
vec4 fg = calculate_foreground();
|
vec4 fg = calculate_foreground(background);
|
||||||
#ifdef TRANSPARENT
|
#ifdef TRANSPARENT
|
||||||
final_color = alpha_blend_premul(fg.rgb, fg.a, background.rgb * bg_alpha, bg_alpha);
|
final_color = alpha_blend_premul(fg, vec4_premul(background, bg_alpha));
|
||||||
#else
|
#else
|
||||||
final_color = blend_onto_opaque_premul(fg.rgb, fg.a, background.rgb);
|
final_color = alpha_blend_premul(fg, background);
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef SPECIAL
|
#ifdef SPECIAL
|
||||||
#ifdef TRANSPARENT
|
#ifdef TRANSPARENT
|
||||||
final_color = vec4(background.rgb * bg_alpha, bg_alpha);
|
final_color = vec4_premul(background, bg_alpha);
|
||||||
#else
|
#else
|
||||||
final_color = vec4(background.rgb, bg_alpha);
|
final_color = vec4(background, bg_alpha);
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef BACKGROUND
|
#ifdef BACKGROUND
|
||||||
#if defined(TRANSPARENT)
|
#if defined(TRANSPARENT)
|
||||||
final_color = vec4(background.rgb * bg_alpha, bg_alpha);
|
final_color = vec4_premul(background, bg_alpha);
|
||||||
#else
|
#else
|
||||||
final_color = vec4(background.rgb, draw_bg);
|
final_color = vec4(background, draw_bg);
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
@ -29,6 +29,7 @@ uniform uint draw_bg_bitfield;
|
|||||||
layout(location=0) in uvec3 colors;
|
layout(location=0) in uvec3 colors;
|
||||||
layout(location=1) in uvec4 sprite_coords;
|
layout(location=1) in uvec4 sprite_coords;
|
||||||
layout(location=2) in uint is_selected;
|
layout(location=2) in uint is_selected;
|
||||||
|
uniform float gamma_lut[256];
|
||||||
|
|
||||||
|
|
||||||
const int fg_index_map[] = int[3](0, 1, 0);
|
const int fg_index_map[] = int[3](0, 1, 0);
|
||||||
@ -87,7 +88,7 @@ vec3 color_to_vec(uint c) {
|
|||||||
r = (c >> 16) & BYTE_MASK;
|
r = (c >> 16) & BYTE_MASK;
|
||||||
g = (c >> 8) & BYTE_MASK;
|
g = (c >> 8) & BYTE_MASK;
|
||||||
b = c & BYTE_MASK;
|
b = c & BYTE_MASK;
|
||||||
return vec3(float(r) / 255.0, float(g) / 255.0, float(b) / 255.0);
|
return vec3(gamma_lut[r], gamma_lut[g], gamma_lut[b]);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint resolve_color(uint c, uint defval) {
|
uint resolve_color(uint c, uint defval) {
|
||||||
|
|||||||
@ -71,7 +71,7 @@ update_surface_size(int w, int h, GLuint offscreen_texture_id) {
|
|||||||
glViewport(0, 0, w, h);
|
glViewport(0, 0, w, h);
|
||||||
if (offscreen_texture_id) {
|
if (offscreen_texture_id) {
|
||||||
glBindTexture(GL_TEXTURE_2D, offscreen_texture_id);
|
glBindTexture(GL_TEXTURE_2D, offscreen_texture_id);
|
||||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
|
glTexImage2D(GL_TEXTURE_2D, 0, GL_SRGB_ALPHA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -11,6 +11,7 @@
|
|||||||
#include "charsets.h"
|
#include "charsets.h"
|
||||||
#include <structmember.h>
|
#include <structmember.h>
|
||||||
#include "glfw-wrapper.h"
|
#include "glfw-wrapper.h"
|
||||||
|
#include "gl.h"
|
||||||
#ifndef __APPLE__
|
#ifndef __APPLE__
|
||||||
#include "freetype_render_ui_text.h"
|
#include "freetype_render_ui_text.h"
|
||||||
#endif
|
#endif
|
||||||
@ -870,6 +871,8 @@ create_os_window(PyObject UNUSED *self, PyObject *args, PyObject *kw) {
|
|||||||
if (is_first_window) {
|
if (is_first_window) {
|
||||||
gl_init();
|
gl_init();
|
||||||
}
|
}
|
||||||
|
// Will make the GPU automatically apply SRGB gamma curve on the resulting framebuffer
|
||||||
|
glEnable(GL_FRAMEBUFFER_SRGB);
|
||||||
bool is_semi_transparent = glfwGetWindowAttrib(glfw_window, GLFW_TRANSPARENT_FRAMEBUFFER);
|
bool is_semi_transparent = glfwGetWindowAttrib(glfw_window, GLFW_TRANSPARENT_FRAMEBUFFER);
|
||||||
// blank the window once so that there is no initial flash of color
|
// blank the window once so that there is no initial flash of color
|
||||||
// changing, in case the background color is not black
|
// changing, in case the background color is not black
|
||||||
|
|||||||
@ -230,6 +230,41 @@ The style with which undercurls are rendered. This option takes the form
|
|||||||
:code:`(thin|thick)-(sparse|dense)`. Thin and thick control the thickness of the
|
:code:`(thin|thick)-(sparse|dense)`. Thin and thick control the thickness of the
|
||||||
undercurl. Sparse and dense control how often the curl oscillates. With sparse
|
undercurl. Sparse and dense control how often the curl oscillates. With sparse
|
||||||
the curl will peak once per character, with dense twice.
|
the curl will peak once per character, with dense twice.
|
||||||
|
'''
|
||||||
|
)
|
||||||
|
|
||||||
|
opt('text_old_gamma', 'no',
|
||||||
|
option_type='to_bool', ctype='bool',
|
||||||
|
long_text='''
|
||||||
|
If to simulate the old gamma-incorrect blending for the text alpha-channel, this
|
||||||
|
will make some text appear like the strokes are uneven. Dark text on bright backgrounds
|
||||||
|
will also look thicker while lighter text on darker backgrounds will look thinner.
|
||||||
|
'''
|
||||||
|
)
|
||||||
|
|
||||||
|
opt('text_gamma_adjustment', '1.0',
|
||||||
|
option_type='positive_float', ctype='float',
|
||||||
|
long_text='''
|
||||||
|
This setting adjusts the thickness of darker text on lighter backgrounds. Increasing the value
|
||||||
|
setting will make the text appear thicker while decreasing the value will make it thinner. It
|
||||||
|
can compensate for some fonts looking too-thin when using the gamma-correct alpha blending.
|
||||||
|
|
||||||
|
The result is scaled based on the luminance difference between the background and the foreground.
|
||||||
|
Dark text on light backgrounds receive the full impact of the curve while light text on dark
|
||||||
|
backgrounds are affected very little.
|
||||||
|
|
||||||
|
Range: >=0.01
|
||||||
|
MacOS: 1.7
|
||||||
|
'''
|
||||||
|
)
|
||||||
|
|
||||||
|
opt('text_contrast', '0',
|
||||||
|
option_type='positive_float', ctype='float',
|
||||||
|
long_text='''
|
||||||
|
Additional multiplicative text contrast as a percentage, will saturate and cause jagged edges if set too high.
|
||||||
|
|
||||||
|
Range: >=0.0
|
||||||
|
MacOS: 30
|
||||||
'''
|
'''
|
||||||
)
|
)
|
||||||
egr() # }}}
|
egr() # }}}
|
||||||
|
|||||||
9
kitty/options/parse.py
generated
9
kitty/options/parse.py
generated
@ -1278,6 +1278,15 @@ class Parser:
|
|||||||
def term(self, val: str, ans: typing.Dict[str, typing.Any]) -> None:
|
def term(self, val: str, ans: typing.Dict[str, typing.Any]) -> None:
|
||||||
ans['term'] = str(val)
|
ans['term'] = str(val)
|
||||||
|
|
||||||
|
def text_contrast(self, val: str, ans: typing.Dict[str, typing.Any]) -> None:
|
||||||
|
ans['text_contrast'] = positive_float(val)
|
||||||
|
|
||||||
|
def text_gamma_adjustment(self, val: str, ans: typing.Dict[str, typing.Any]) -> None:
|
||||||
|
ans['text_gamma_adjustment'] = positive_float(val)
|
||||||
|
|
||||||
|
def text_old_gamma(self, val: str, ans: typing.Dict[str, typing.Any]) -> None:
|
||||||
|
ans['text_old_gamma'] = to_bool(val)
|
||||||
|
|
||||||
def touch_scroll_multiplier(self, val: str, ans: typing.Dict[str, typing.Any]) -> None:
|
def touch_scroll_multiplier(self, val: str, ans: typing.Dict[str, typing.Any]) -> None:
|
||||||
ans['touch_scroll_multiplier'] = float(val)
|
ans['touch_scroll_multiplier'] = float(val)
|
||||||
|
|
||||||
|
|||||||
45
kitty/options/to-c-generated.h
generated
45
kitty/options/to-c-generated.h
generated
@ -57,6 +57,45 @@ convert_from_opts_modify_font(PyObject *py_opts, Options *opts) {
|
|||||||
Py_DECREF(ret);
|
Py_DECREF(ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
convert_from_python_text_old_gamma(PyObject *val, Options *opts) {
|
||||||
|
opts->text_old_gamma = PyObject_IsTrue(val);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
convert_from_opts_text_old_gamma(PyObject *py_opts, Options *opts) {
|
||||||
|
PyObject *ret = PyObject_GetAttrString(py_opts, "text_old_gamma");
|
||||||
|
if (ret == NULL) return;
|
||||||
|
convert_from_python_text_old_gamma(ret, opts);
|
||||||
|
Py_DECREF(ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
convert_from_python_text_gamma_adjustment(PyObject *val, Options *opts) {
|
||||||
|
opts->text_gamma_adjustment = PyFloat_AsFloat(val);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
convert_from_opts_text_gamma_adjustment(PyObject *py_opts, Options *opts) {
|
||||||
|
PyObject *ret = PyObject_GetAttrString(py_opts, "text_gamma_adjustment");
|
||||||
|
if (ret == NULL) return;
|
||||||
|
convert_from_python_text_gamma_adjustment(ret, opts);
|
||||||
|
Py_DECREF(ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
convert_from_python_text_contrast(PyObject *val, Options *opts) {
|
||||||
|
opts->text_contrast = PyFloat_AsFloat(val);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
convert_from_opts_text_contrast(PyObject *py_opts, Options *opts) {
|
||||||
|
PyObject *ret = PyObject_GetAttrString(py_opts, "text_contrast");
|
||||||
|
if (ret == NULL) return;
|
||||||
|
convert_from_python_text_contrast(ret, opts);
|
||||||
|
Py_DECREF(ret);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
convert_from_python_cursor_shape(PyObject *val, Options *opts) {
|
convert_from_python_cursor_shape(PyObject *val, Options *opts) {
|
||||||
opts->cursor_shape = PyLong_AsLong(val);
|
opts->cursor_shape = PyLong_AsLong(val);
|
||||||
@ -1042,6 +1081,12 @@ convert_opts_from_python_opts(PyObject *py_opts, Options *opts) {
|
|||||||
if (PyErr_Occurred()) return false;
|
if (PyErr_Occurred()) return false;
|
||||||
convert_from_opts_modify_font(py_opts, opts);
|
convert_from_opts_modify_font(py_opts, opts);
|
||||||
if (PyErr_Occurred()) return false;
|
if (PyErr_Occurred()) return false;
|
||||||
|
convert_from_opts_text_old_gamma(py_opts, opts);
|
||||||
|
if (PyErr_Occurred()) return false;
|
||||||
|
convert_from_opts_text_gamma_adjustment(py_opts, opts);
|
||||||
|
if (PyErr_Occurred()) return false;
|
||||||
|
convert_from_opts_text_contrast(py_opts, opts);
|
||||||
|
if (PyErr_Occurred()) return false;
|
||||||
convert_from_opts_cursor_shape(py_opts, opts);
|
convert_from_opts_cursor_shape(py_opts, opts);
|
||||||
if (PyErr_Occurred()) return false;
|
if (PyErr_Occurred()) return false;
|
||||||
convert_from_opts_cursor_beam_thickness(py_opts, opts);
|
convert_from_opts_cursor_beam_thickness(py_opts, opts);
|
||||||
|
|||||||
6
kitty/options/types.py
generated
6
kitty/options/types.py
generated
@ -443,6 +443,9 @@ option_names = ( # {{{
|
|||||||
'tab_title_max_length',
|
'tab_title_max_length',
|
||||||
'tab_title_template',
|
'tab_title_template',
|
||||||
'term',
|
'term',
|
||||||
|
'text_contrast',
|
||||||
|
'text_gamma_adjustment',
|
||||||
|
'text_old_gamma',
|
||||||
'touch_scroll_multiplier',
|
'touch_scroll_multiplier',
|
||||||
'undercurl_style',
|
'undercurl_style',
|
||||||
'update_check_interval',
|
'update_check_interval',
|
||||||
@ -594,6 +597,9 @@ class Options:
|
|||||||
tab_title_max_length: int = 0
|
tab_title_max_length: int = 0
|
||||||
tab_title_template: str = '{fmt.fg.red}{bell_symbol}{activity_symbol}{fmt.fg.tab}{title}'
|
tab_title_template: str = '{fmt.fg.red}{bell_symbol}{activity_symbol}{fmt.fg.tab}{title}'
|
||||||
term: str = 'xterm-kitty'
|
term: str = 'xterm-kitty'
|
||||||
|
text_contrast: float = 0
|
||||||
|
text_gamma_adjustment: float = 1.0
|
||||||
|
text_old_gamma: bool = False
|
||||||
touch_scroll_multiplier: float = 1.0
|
touch_scroll_multiplier: float = 1.0
|
||||||
undercurl_style: choices_for_undercurl_style = 'thin-sparse'
|
undercurl_style: choices_for_undercurl_style = 'thin-sparse'
|
||||||
update_check_interval: float = 24.0
|
update_check_interval: float = 24.0
|
||||||
|
|||||||
@ -10,6 +10,7 @@
|
|||||||
#include "colors.h"
|
#include "colors.h"
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include "window_logo.h"
|
#include "window_logo.h"
|
||||||
|
#include "srgb_gamma.h"
|
||||||
|
|
||||||
#define BLEND_ONTO_OPAQUE glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); // blending onto opaque colors
|
#define BLEND_ONTO_OPAQUE glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); // blending onto opaque colors
|
||||||
#define BLEND_ONTO_OPAQUE_WITH_OPAQUE_OUTPUT glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ZERO, GL_ONE); // blending onto opaque colors with final color having alpha 1
|
#define BLEND_ONTO_OPAQUE_WITH_OPAQUE_OUTPUT glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ZERO, GL_ONE); // blending onto opaque colors with final color having alpha 1
|
||||||
@ -29,6 +30,16 @@ typedef struct {
|
|||||||
static const SpriteMap NEW_SPRITE_MAP = { .xnum = 1, .ynum = 1, .last_num_of_layers = 1, .last_ynum = -1 };
|
static const SpriteMap NEW_SPRITE_MAP = { .xnum = 1, .ynum = 1, .last_num_of_layers = 1, .last_ynum = -1 };
|
||||||
static GLint max_texture_size = 0, max_array_texture_layers = 0;
|
static GLint max_texture_size = 0, max_array_texture_layers = 0;
|
||||||
|
|
||||||
|
GLfloat
|
||||||
|
srgb_color(uint8_t color) {
|
||||||
|
return srgb_lut[color];
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
color_vec3(GLint location, color_type color) {
|
||||||
|
glUniform3f(location, srgb_lut[(color >> 16) & 0xFF], srgb_lut[(color >> 8) & 0xFF], srgb_lut[color & 0xFF]);
|
||||||
|
}
|
||||||
|
|
||||||
SPRITE_MAP_HANDLE
|
SPRITE_MAP_HANDLE
|
||||||
alloc_sprite_map(unsigned int cell_width, unsigned int cell_height) {
|
alloc_sprite_map(unsigned int cell_width, unsigned int cell_height) {
|
||||||
if (!max_texture_size) {
|
if (!max_texture_size) {
|
||||||
@ -102,7 +113,7 @@ realloc_sprite_texture(FONTS_DATA_HANDLE fg) {
|
|||||||
znum = z + 1;
|
znum = z + 1;
|
||||||
SpriteMap *sprite_map = (SpriteMap*)fg->sprite_map;
|
SpriteMap *sprite_map = (SpriteMap*)fg->sprite_map;
|
||||||
width = xnum * sprite_map->cell_width; height = ynum * sprite_map->cell_height;
|
width = xnum * sprite_map->cell_width; height = ynum * sprite_map->cell_height;
|
||||||
glTexStorage3D(GL_TEXTURE_2D_ARRAY, 1, GL_RGBA8, width, height, znum);
|
glTexStorage3D(GL_TEXTURE_2D_ARRAY, 1, GL_SRGB8_ALPHA8, width, height, znum);
|
||||||
if (sprite_map->texture_id) {
|
if (sprite_map->texture_id) {
|
||||||
// need to re-alloc
|
// need to re-alloc
|
||||||
src_ynum = MAX(1, sprite_map->last_ynum);
|
src_ynum = MAX(1, sprite_map->last_ynum);
|
||||||
@ -159,7 +170,7 @@ send_image_to_gpu(GLuint *tex_id, const void* data, GLsizei width, GLsizei heigh
|
|||||||
}
|
}
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, r);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, r);
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, r);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, r);
|
||||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, is_opaque ? GL_RGB : GL_RGBA, GL_UNSIGNED_BYTE, data);
|
glTexImage2D(GL_TEXTURE_2D, 0, GL_SRGB_ALPHA, width, height, 0, is_opaque ? GL_RGB : GL_RGBA, GL_UNSIGNED_BYTE, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
// }}}
|
// }}}
|
||||||
@ -498,9 +509,7 @@ draw_centered_alpha_mask(OSWindow *os_window, size_t screen_width, size_t screen
|
|||||||
gpu_data_for_centered_image(data, screen_width, screen_height, width, height);
|
gpu_data_for_centered_image(data, screen_width, screen_height, width, height);
|
||||||
bind_program(GRAPHICS_ALPHA_MASK_PROGRAM);
|
bind_program(GRAPHICS_ALPHA_MASK_PROGRAM);
|
||||||
glUniform1i(cell_uniform_data.amask_image_loc, GRAPHICS_UNIT);
|
glUniform1i(cell_uniform_data.amask_image_loc, GRAPHICS_UNIT);
|
||||||
#define CV3(x) (((float)((x >> 16) & 0xff))/255.f), (((float)((x >> 8) & 0xff))/255.f), (((float)(x & 0xff))/255.f)
|
color_vec3(cell_uniform_data.amask_fg_loc, OPT(foreground));
|
||||||
glUniform3f(cell_uniform_data.amask_fg_loc, CV3(OPT(foreground)));
|
|
||||||
#undef CV3
|
|
||||||
glUniform1f(cell_uniform_data.amask_premult_loc, os_window->is_semi_transparent ? 1.f : 0.f);
|
glUniform1f(cell_uniform_data.amask_premult_loc, os_window->is_semi_transparent ? 1.f : 0.f);
|
||||||
send_graphics_data_to_gpu(1, os_window->gvao_idx, data);
|
send_graphics_data_to_gpu(1, os_window->gvao_idx, data);
|
||||||
glEnable(GL_BLEND);
|
glEnable(GL_BLEND);
|
||||||
@ -536,7 +545,7 @@ draw_tint(bool premult, Screen *screen, const CellRenderData *crd) {
|
|||||||
if (premult) { BLEND_PREMULT } else { BLEND_ONTO_OPAQUE_WITH_OPAQUE_OUTPUT }
|
if (premult) { BLEND_PREMULT } else { BLEND_ONTO_OPAQUE_WITH_OPAQUE_OUTPUT }
|
||||||
bind_program(TINT_PROGRAM);
|
bind_program(TINT_PROGRAM);
|
||||||
color_type window_bg = colorprofile_to_color(screen->color_profile, screen->color_profile->overridden.default_bg, screen->color_profile->configured.default_bg).rgb;
|
color_type window_bg = colorprofile_to_color(screen->color_profile, screen->color_profile->overridden.default_bg, screen->color_profile->configured.default_bg).rgb;
|
||||||
#define C(shift) ((((GLfloat)((window_bg >> shift) & 0xFF)) / 255.0f)) * premult_factor
|
#define C(shift) srgb_color((window_bg >> shift) & 0xFF) * premult_factor
|
||||||
GLfloat premult_factor = premult ? OPT(background_tint) : 1.0f;
|
GLfloat premult_factor = premult ? OPT(background_tint) : 1.0f;
|
||||||
glUniform4f(tint_program_layout.tint_color_location, C(16), C(8), C(0), OPT(background_tint));
|
glUniform4f(tint_program_layout.tint_color_location, C(16), C(8), C(0), OPT(background_tint));
|
||||||
#undef C
|
#undef C
|
||||||
@ -560,7 +569,17 @@ set_cell_uniforms(float current_inactive_text_alpha, bool force) {
|
|||||||
S(CELL_PROGRAM, sprites, SPRITE_MAP_UNIT, 1i); S(CELL_FG_PROGRAM, sprites, SPRITE_MAP_UNIT, 1i);
|
S(CELL_PROGRAM, sprites, SPRITE_MAP_UNIT, 1i); S(CELL_FG_PROGRAM, sprites, SPRITE_MAP_UNIT, 1i);
|
||||||
S(CELL_PROGRAM, dim_opacity, OPT(dim_opacity), 1f); S(CELL_FG_PROGRAM, dim_opacity, OPT(dim_opacity), 1f);
|
S(CELL_PROGRAM, dim_opacity, OPT(dim_opacity), 1f); S(CELL_FG_PROGRAM, dim_opacity, OPT(dim_opacity), 1f);
|
||||||
S(CELL_BG_PROGRAM, defaultbg, OPT(background), 1f);
|
S(CELL_BG_PROGRAM, defaultbg, OPT(background), 1f);
|
||||||
|
int text_old_gamma = OPT(text_old_gamma) ? 1 : 0;
|
||||||
|
S(CELL_PROGRAM, text_old_gamma, text_old_gamma, 1i); S(CELL_FG_PROGRAM, text_old_gamma, text_old_gamma, 1i);
|
||||||
|
float text_contrast = 1.0f + OPT(text_contrast) * 0.01f;
|
||||||
|
S(CELL_PROGRAM, text_contrast, text_contrast, 1f); S(CELL_FG_PROGRAM, text_contrast, text_contrast, 1f);
|
||||||
|
float text_gamma_adjustment = OPT(text_gamma_adjustment) < 0.01f ? 1.0f : 1.0f / OPT(text_gamma_adjustment);
|
||||||
|
S(CELL_PROGRAM, text_gamma_adjustment, text_gamma_adjustment, 1f); S(CELL_FG_PROGRAM, text_gamma_adjustment, text_gamma_adjustment, 1f);
|
||||||
#undef S
|
#undef S
|
||||||
|
#define SV(prog, name, num, val, type) { bind_program(prog); glUniform##type(glGetUniformLocation(program_id(prog), #name), num, val); }
|
||||||
|
SV(CELL_PROGRAM, gamma_lut, 256, srgb_lut, 1fv); SV(CELL_FG_PROGRAM, gamma_lut, 256, srgb_lut, 1fv);
|
||||||
|
SV(CELL_BG_PROGRAM, gamma_lut, 256, srgb_lut, 1fv); SV(CELL_SPECIAL_PROGRAM, gamma_lut, 256, srgb_lut, 1fv);
|
||||||
|
#undef SV
|
||||||
cell_uniform_data.constants_set = true;
|
cell_uniform_data.constants_set = true;
|
||||||
}
|
}
|
||||||
if (current_inactive_text_alpha != cell_uniform_data.prev_inactive_text_alpha || force) {
|
if (current_inactive_text_alpha != cell_uniform_data.prev_inactive_text_alpha || force) {
|
||||||
@ -612,7 +631,7 @@ render_a_bar(OSWindow *os_window, Screen *screen, const CellRenderData *crd, Win
|
|||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, bar_width, bar_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, bar->buf);
|
glTexImage2D(GL_TEXTURE_2D, 0, GL_SRGB_ALPHA, bar_width, bar_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, bar->buf);
|
||||||
set_cell_uniforms(1.f, false);
|
set_cell_uniforms(1.f, false);
|
||||||
bind_program(GRAPHICS_PROGRAM);
|
bind_program(GRAPHICS_PROGRAM);
|
||||||
send_graphics_data_to_gpu(1, os_window->gvao_idx, &data);
|
send_graphics_data_to_gpu(1, os_window->gvao_idx, &data);
|
||||||
@ -707,9 +726,7 @@ draw_window_number(OSWindow *os_window, Screen *screen, const CellRenderData *cr
|
|||||||
BLEND_PREMULT;
|
BLEND_PREMULT;
|
||||||
glUniform1i(cell_uniform_data.amask_image_loc, GRAPHICS_UNIT);
|
glUniform1i(cell_uniform_data.amask_image_loc, GRAPHICS_UNIT);
|
||||||
color_type digit_color = colorprofile_to_color_with_fallback(screen->color_profile, screen->color_profile->overridden.highlight_bg, screen->color_profile->configured.highlight_bg, screen->color_profile->overridden.default_fg, screen->color_profile->configured.default_fg);
|
color_type digit_color = colorprofile_to_color_with_fallback(screen->color_profile, screen->color_profile->overridden.highlight_bg, screen->color_profile->configured.highlight_bg, screen->color_profile->overridden.default_fg, screen->color_profile->configured.default_fg);
|
||||||
#define CV3(x) (((float)((x >> 16) & 0xff))/255.f), (((float)((x >> 8) & 0xff))/255.f), (((float)(x & 0xff))/255.f)
|
color_vec3(cell_uniform_data.amask_fg_loc, digit_color);
|
||||||
glUniform3f(cell_uniform_data.amask_fg_loc, CV3(digit_color));
|
|
||||||
#undef CV3
|
|
||||||
glUniform1f(cell_uniform_data.amask_premult_loc, 1.f);
|
glUniform1f(cell_uniform_data.amask_premult_loc, 1.f);
|
||||||
send_graphics_data_to_gpu(1, os_window->gvao_idx, ird);
|
send_graphics_data_to_gpu(1, os_window->gvao_idx, ird);
|
||||||
draw_graphics(GRAPHICS_ALPHA_MASK_PROGRAM, 0, os_window->gvao_idx, ird, 0, 1);
|
draw_graphics(GRAPHICS_ALPHA_MASK_PROGRAM, 0, os_window->gvao_idx, ird, 0, 1);
|
||||||
@ -726,7 +743,7 @@ draw_visual_bell_flash(GLfloat intensity, const CellRenderData *crd, Screen *scr
|
|||||||
#define COLOR(name, fallback) colorprofile_to_color_with_fallback(screen->color_profile, screen->color_profile->overridden.name, screen->color_profile->configured.name, screen->color_profile->overridden.fallback, screen->color_profile->configured.fallback)
|
#define COLOR(name, fallback) colorprofile_to_color_with_fallback(screen->color_profile, screen->color_profile->overridden.name, screen->color_profile->configured.name, screen->color_profile->overridden.fallback, screen->color_profile->configured.fallback)
|
||||||
const color_type flash = !IS_SPECIAL_COLOR(highlight_bg) ? COLOR(visual_bell_color, highlight_bg) : COLOR(visual_bell_color, default_fg);
|
const color_type flash = !IS_SPECIAL_COLOR(highlight_bg) ? COLOR(visual_bell_color, highlight_bg) : COLOR(visual_bell_color, default_fg);
|
||||||
#undef COLOR
|
#undef COLOR
|
||||||
#define C(shift) ((((GLfloat)((flash >> shift) & 0xFF)) / 255.0f) )
|
#define C(shift) srgb_color((flash >> shift) & 0xFF)
|
||||||
const GLfloat r = C(16), g = C(8), b = C(0);
|
const GLfloat r = C(16), g = C(8), b = C(0);
|
||||||
const GLfloat max_channel = r > g ? (r > b ? r : b) : (g > b ? g : b);
|
const GLfloat max_channel = r > g ? (r > b ? r : b) : (g > b ? g : b);
|
||||||
#undef C
|
#undef C
|
||||||
@ -793,7 +810,7 @@ draw_cells_interleaved_premult(ssize_t vao_idx, ssize_t gvao_idx, Screen *screen
|
|||||||
glGenFramebuffers(1, &os_window->offscreen_framebuffer);
|
glGenFramebuffers(1, &os_window->offscreen_framebuffer);
|
||||||
glGenTextures(1, &os_window->offscreen_texture_id);
|
glGenTextures(1, &os_window->offscreen_texture_id);
|
||||||
glBindTexture(GL_TEXTURE_2D, os_window->offscreen_texture_id);
|
glBindTexture(GL_TEXTURE_2D, os_window->offscreen_texture_id);
|
||||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, os_window->viewport_width, os_window->viewport_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
|
glTexImage2D(GL_TEXTURE_2D, 0, GL_SRGB_ALPHA, os_window->viewport_width, os_window->viewport_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||||
@ -862,7 +879,7 @@ draw_cells_interleaved_premult(ssize_t vao_idx, ssize_t gvao_idx, Screen *screen
|
|||||||
void
|
void
|
||||||
blank_canvas(float background_opacity, color_type color) {
|
blank_canvas(float background_opacity, color_type color) {
|
||||||
// See https://github.com/glfw/glfw/issues/1538 for why we use pre-multiplied alpha
|
// See https://github.com/glfw/glfw/issues/1538 for why we use pre-multiplied alpha
|
||||||
#define C(shift) ((((GLfloat)((color >> shift) & 0xFF)) / 255.0f) * background_opacity)
|
#define C(shift) srgb_color((color >> shift) & 0xFF)
|
||||||
glClearColor(C(16), C(8), C(0), background_opacity);
|
glClearColor(C(16), C(8), C(0), background_opacity);
|
||||||
#undef C
|
#undef C
|
||||||
glClear(GL_COLOR_BUFFER_BIT);
|
glClear(GL_COLOR_BUFFER_BIT);
|
||||||
@ -966,7 +983,7 @@ draw_cells(ssize_t vao_idx, ssize_t gvao_idx, const ScreenRenderData *srd, float
|
|||||||
// }}}
|
// }}}
|
||||||
|
|
||||||
// Borders {{{
|
// Borders {{{
|
||||||
enum BorderUniforms { BORDER_viewport, BORDER_background_opacity, BORDER_tint_opacity, BORDER_tint_premult, BORDER_colors, NUM_BORDER_UNIFORMS };
|
enum BorderUniforms { BORDER_viewport, BORDER_background_opacity, BORDER_tint_opacity, BORDER_tint_premult, BORDER_colors, BORDER_gamma_lut, NUM_BORDER_UNIFORMS };
|
||||||
static GLint border_uniform_locations[NUM_BORDER_UNIFORMS] = {0};
|
static GLint border_uniform_locations[NUM_BORDER_UNIFORMS] = {0};
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -977,6 +994,7 @@ init_borders_program(void) {
|
|||||||
SET_LOC(tint_opacity)
|
SET_LOC(tint_opacity)
|
||||||
SET_LOC(tint_premult)
|
SET_LOC(tint_premult)
|
||||||
SET_LOC(colors)
|
SET_LOC(colors)
|
||||||
|
SET_LOC(gamma_lut)
|
||||||
#undef SET_LOC
|
#undef SET_LOC
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1028,6 +1046,7 @@ draw_borders(ssize_t vao_idx, unsigned int num_border_rects, BorderRect *rect_bu
|
|||||||
glUniform1f(border_uniform_locations[BORDER_tint_opacity], tint_opacity);
|
glUniform1f(border_uniform_locations[BORDER_tint_opacity], tint_opacity);
|
||||||
glUniform1f(border_uniform_locations[BORDER_tint_premult], tint_premult);
|
glUniform1f(border_uniform_locations[BORDER_tint_premult], tint_premult);
|
||||||
glUniform2ui(border_uniform_locations[BORDER_viewport], viewport_width, viewport_height);
|
glUniform2ui(border_uniform_locations[BORDER_viewport], viewport_width, viewport_height);
|
||||||
|
glUniform1fv(border_uniform_locations[BORDER_gamma_lut], 256, srgb_lut);
|
||||||
if (has_bgimage(w)) {
|
if (has_bgimage(w)) {
|
||||||
if (w->is_semi_transparent) { BLEND_PREMULT; }
|
if (w->is_semi_transparent) { BLEND_PREMULT; }
|
||||||
else { BLEND_ONTO_OPAQUE_WITH_OPAQUE_OUTPUT; }
|
else { BLEND_ONTO_OPAQUE_WITH_OPAQUE_OUTPUT; }
|
||||||
|
|||||||
21
kitty/srgb_gamma.c
Normal file
21
kitty/srgb_gamma.c
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
// Generated by gen-srgb-lut.py DO NOT edit
|
||||||
|
#include "srgb_gamma.h"
|
||||||
|
|
||||||
|
const GLfloat srgb_lut[256] = {
|
||||||
|
0.00000f, 0.00030f, 0.00061f, 0.00091f, 0.00121f, 0.00152f, 0.00182f, 0.00212f, 0.00243f, 0.00273f, 0.00304f, 0.00335f, 0.00368f, 0.00402f, 0.00439f, 0.00478f,
|
||||||
|
0.00518f, 0.00561f, 0.00605f, 0.00651f, 0.00700f, 0.00750f, 0.00802f, 0.00857f, 0.00913f, 0.00972f, 0.01033f, 0.01096f, 0.01161f, 0.01229f, 0.01298f, 0.01370f,
|
||||||
|
0.01444f, 0.01521f, 0.01600f, 0.01681f, 0.01764f, 0.01850f, 0.01938f, 0.02029f, 0.02122f, 0.02217f, 0.02315f, 0.02416f, 0.02519f, 0.02624f, 0.02732f, 0.02843f,
|
||||||
|
0.02956f, 0.03071f, 0.03190f, 0.03310f, 0.03434f, 0.03560f, 0.03689f, 0.03820f, 0.03955f, 0.04092f, 0.04231f, 0.04374f, 0.04519f, 0.04667f, 0.04817f, 0.04971f,
|
||||||
|
0.05127f, 0.05286f, 0.05448f, 0.05613f, 0.05781f, 0.05951f, 0.06125f, 0.06301f, 0.06480f, 0.06663f, 0.06848f, 0.07036f, 0.07227f, 0.07421f, 0.07619f, 0.07819f,
|
||||||
|
0.08022f, 0.08228f, 0.08438f, 0.08650f, 0.08866f, 0.09084f, 0.09306f, 0.09531f, 0.09759f, 0.09990f, 0.10224f, 0.10462f, 0.10702f, 0.10946f, 0.11193f, 0.11444f,
|
||||||
|
0.11697f, 0.11954f, 0.12214f, 0.12477f, 0.12744f, 0.13014f, 0.13287f, 0.13563f, 0.13843f, 0.14126f, 0.14413f, 0.14703f, 0.14996f, 0.15293f, 0.15593f, 0.15896f,
|
||||||
|
0.16203f, 0.16513f, 0.16827f, 0.17144f, 0.17465f, 0.17789f, 0.18116f, 0.18447f, 0.18782f, 0.19120f, 0.19462f, 0.19807f, 0.20156f, 0.20508f, 0.20864f, 0.21223f,
|
||||||
|
0.21586f, 0.21953f, 0.22323f, 0.22697f, 0.23074f, 0.23455f, 0.23840f, 0.24228f, 0.24620f, 0.25016f, 0.25415f, 0.25818f, 0.26225f, 0.26636f, 0.27050f, 0.27468f,
|
||||||
|
0.27889f, 0.28315f, 0.28744f, 0.29177f, 0.29614f, 0.30054f, 0.30499f, 0.30947f, 0.31399f, 0.31855f, 0.32314f, 0.32778f, 0.33245f, 0.33716f, 0.34191f, 0.34670f,
|
||||||
|
0.35153f, 0.35640f, 0.36131f, 0.36625f, 0.37124f, 0.37626f, 0.38133f, 0.38643f, 0.39157f, 0.39676f, 0.40198f, 0.40724f, 0.41254f, 0.41789f, 0.42327f, 0.42869f,
|
||||||
|
0.43415f, 0.43966f, 0.44520f, 0.45079f, 0.45641f, 0.46208f, 0.46778f, 0.47353f, 0.47932f, 0.48515f, 0.49102f, 0.49693f, 0.50289f, 0.50888f, 0.51492f, 0.52100f,
|
||||||
|
0.52712f, 0.53328f, 0.53948f, 0.54572f, 0.55201f, 0.55834f, 0.56471f, 0.57112f, 0.57758f, 0.58408f, 0.59062f, 0.59720f, 0.60383f, 0.61050f, 0.61721f, 0.62396f,
|
||||||
|
0.63076f, 0.63760f, 0.64448f, 0.65141f, 0.65837f, 0.66539f, 0.67244f, 0.67954f, 0.68669f, 0.69387f, 0.70110f, 0.70838f, 0.71569f, 0.72306f, 0.73046f, 0.73791f,
|
||||||
|
0.74540f, 0.75294f, 0.76052f, 0.76815f, 0.77582f, 0.78354f, 0.79130f, 0.79910f, 0.80695f, 0.81485f, 0.82279f, 0.83077f, 0.83880f, 0.84687f, 0.85499f, 0.86316f,
|
||||||
|
0.87137f, 0.87962f, 0.88792f, 0.89627f, 0.90466f, 0.91310f, 0.92158f, 0.93011f, 0.93869f, 0.94731f, 0.95597f, 0.96469f, 0.97345f, 0.98225f, 0.99110f, 1.00000f,
|
||||||
|
};
|
||||||
4
kitty/srgb_gamma.h
Normal file
4
kitty/srgb_gamma.h
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
#pragma once
|
||||||
|
#include "gl.h"
|
||||||
|
|
||||||
|
extern const GLfloat srgb_lut[256];
|
||||||
@ -47,6 +47,8 @@ typedef struct {
|
|||||||
WindowTitleIn macos_show_window_title_in;
|
WindowTitleIn macos_show_window_title_in;
|
||||||
char *bell_path;
|
char *bell_path;
|
||||||
float background_opacity, dim_opacity;
|
float background_opacity, dim_opacity;
|
||||||
|
float text_contrast, text_gamma_adjustment;
|
||||||
|
bool text_old_gamma;
|
||||||
|
|
||||||
char *background_image, *default_window_logo;
|
char *background_image, *default_window_logo;
|
||||||
BackgroundImageLayout background_image_layout;
|
BackgroundImageLayout background_image_layout;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user