Avoid very low contrast colors for reverse video cursor

This commit is contained in:
Kovid Goyal 2021-10-28 14:14:38 +05:30
parent 93dbcab10a
commit c06a03ab96
No known key found for this signature in database
GPG Key ID: 06BC317B515ACE7C
3 changed files with 29 additions and 9 deletions

View File

@ -64,6 +64,7 @@ extern PyTypeObject Color_Type;
static inline double
rgb_luminance(ARGB32 c) {
// From ITU BT 601 http://www.itu.int/rec/R-REC-BT.601
return 0.299 * c.red + 0.587 * c.green + 0.114 * c.blue;
}

View File

@ -214,12 +214,12 @@ agr('cursor', 'Cursor customization')
opt('cursor', '#cccccc',
option_type='to_color_or_none', long_text='''
Default cursor color. If set to the special value :code:`none` the cursor will be
rendered with a "reverse video" effect. It's color will be the color of the text in
the cell it is over and the text will be rendered with the background color of the cell.
Note that if the program running in the terminal sets a cursor color, this takes precedence.
Also, the reverse video effect is not applied if the cell's foreground and background colors
are the same.
Default cursor color. If set to the special value :code:`none` the cursor will
be rendered with a "reverse video" effect. It's color will be the color of the
text in the cell it is over and the text will be rendered with the background
color of the cell. Note that if the program running in the terminal sets a
cursor color, this takes precedence. Also, the cursor colors are modified if
the cell background and foreground colors have very low contrast.
'''
)

View File

@ -7,6 +7,7 @@
#include "fonts.h"
#include "gl.h"
#include "colors.h"
#include <stddef.h>
enum { CELL_PROGRAM, CELL_BG_PROGRAM, CELL_SPECIAL_PROGRAM, CELL_FG_PROGRAM, BORDERS_PROGRAM, GRAPHICS_PROGRAM, GRAPHICS_PREMULT_PROGRAM, GRAPHICS_ALPHA_MASK_PROGRAM, BLIT_PROGRAM, BGIMAGE_PROGRAM, TINT_PROGRAM, SEVEN_SEGMENT_PROGRAM, NUM_PROGRAMS };
@ -257,6 +258,21 @@ send_graphics_data_to_gpu(size_t image_count, ssize_t gvao_idx, const ImageRende
unmap_vao_buffer(gvao_idx, 0); a = NULL;
}
static void
pick_cursor_color(Line *line, ColorProfile *color_profile, color_type cell_fg, color_type cell_bg, index_type cell_color_x, color_type *cursor_fg, color_type *cursor_bg, color_type default_fg, color_type default_bg) {
ARGB32 fg, bg, dfg, dbg;
(void) line; (void) color_profile; (void) cell_color_x;
fg.rgb = cell_fg; bg.rgb = cell_bg;
*cursor_fg = cell_bg; *cursor_bg = cell_fg;
double cell_contrast = rgb_contrast(fg, bg);
if (cell_contrast < 2.5) {
dfg.rgb = default_fg; dbg.rgb = default_bg;
if (rgb_contrast(dfg, dbg) > cell_contrast) {
*cursor_fg = default_bg; *cursor_bg = default_fg;
}
}
}
static void
cell_update_uniform_block(ssize_t vao_idx, Screen *screen, int uniform_buffer, GLfloat xstart, GLfloat ystart, GLfloat dx, GLfloat dy, CursorRenderInfo *cursor, bool inverted, OSWindow *os_window) {
struct CellRenderData {
@ -292,16 +308,19 @@ cell_update_uniform_block(ssize_t vao_idx, Screen *screen, int uniform_buffer, G
}
} else rd->cursor_fg_sprite_idx = UNFOCUSED_IDX;
color_type cell_fg = rd->default_fg, cell_bg = rd->default_bg;
if (screen->cursor->y < screen->lines) {
index_type cell_color_x = screen->cursor->x;
bool cursor_ok = screen->cursor->x < screen->columns && screen->cursor->y < screen->lines;
if (cursor_ok) {
linebuf_init_line(screen->linebuf, screen->cursor->y);
index_type x = screen->cursor->x;
colors_for_cell(screen->linebuf->line, screen->color_profile, &x, &cell_fg, &cell_bg);
colors_for_cell(screen->linebuf->line, screen->color_profile, &cell_color_x, &cell_fg, &cell_bg);
}
if (screen->color_profile->overridden.cursor_color.type == COLOR_IS_INDEX || screen->color_profile->overridden.cursor_color.type == COLOR_IS_RGB) {
// since the program is controlling the cursor color we hope it has chosen one
// that has good contrast with the text color of the cell
rd->cursor_fg = cell_fg; rd->cursor_bg = COLOR(cursor_color);
} else if (IS_SPECIAL_COLOR(cursor_color)) {
if (cursor_ok) pick_cursor_color(screen->linebuf->line, screen->color_profile, cell_fg, cell_bg, cell_color_x, &rd->cursor_fg, &rd->cursor_bg, rd->default_fg, rd->default_bg);
else { rd->cursor_fg = rd->default_bg; rd->cursor_bg = rd->default_fg; }
if (cell_bg == cell_fg) {
rd->cursor_fg = rd->default_bg; rd->cursor_bg = rd->default_fg;
} else { rd->cursor_fg = cell_bg; rd->cursor_bg = cell_fg; }