mirror of
https://codeberg.org/dnkl/foot.git
synced 2026-02-04 04:06:06 -05:00
render: dim and brighten using linear rgb interpolation
Adds setting tweak.dim-amount, similar to bold-text-in-bright-amount. Closes #2006
This commit is contained in:
parent
5f72f51ae8
commit
663c9082db
7 changed files with 51 additions and 66 deletions
|
|
@ -64,6 +64,12 @@
|
||||||
### Changed
|
### Changed
|
||||||
|
|
||||||
* UTF-8 error recovery now discards fewer bytes.
|
* UTF-8 error recovery now discards fewer bytes.
|
||||||
|
* Auto-calculated dimmed and brightened colors (e.g. when custom dim
|
||||||
|
colors has not configured) is now done by linear RGB interpolation,
|
||||||
|
rather than converting to HSL and adjusting the luminance
|
||||||
|
([#2006][2006]).
|
||||||
|
|
||||||
|
[2006]: https://codeberg.org/dnkl/foot/issues/2006
|
||||||
|
|
||||||
|
|
||||||
### Deprecated
|
### Deprecated
|
||||||
|
|
|
||||||
4
config.c
4
config.c
|
|
@ -2759,6 +2759,9 @@ parse_section_tweak(struct context *ctx)
|
||||||
else if (streq(key, "sixel"))
|
else if (streq(key, "sixel"))
|
||||||
return value_to_bool(ctx, &conf->tweak.sixel);
|
return value_to_bool(ctx, &conf->tweak.sixel);
|
||||||
|
|
||||||
|
else if (streq(key, "dim-amount"))
|
||||||
|
return value_to_float(ctx, &conf->dim.amount);
|
||||||
|
|
||||||
else if (streq(key, "bold-text-in-bright-amount"))
|
else if (streq(key, "bold-text-in-bright-amount"))
|
||||||
return value_to_float(ctx, &conf->bold_in_bright.amount);
|
return value_to_float(ctx, &conf->bold_in_bright.amount);
|
||||||
|
|
||||||
|
|
@ -3288,6 +3291,7 @@ config_load(struct config *conf, const char *conf_path,
|
||||||
.resize_by_cells = true,
|
.resize_by_cells = true,
|
||||||
.resize_keep_grid = true,
|
.resize_keep_grid = true,
|
||||||
.resize_delay_ms = 100,
|
.resize_delay_ms = 100,
|
||||||
|
.dim = { .amount = 1.5 },
|
||||||
.bold_in_bright = {
|
.bold_in_bright = {
|
||||||
.enabled = false,
|
.enabled = false,
|
||||||
.palette_based = false,
|
.palette_based = false,
|
||||||
|
|
|
||||||
4
config.h
4
config.h
|
|
@ -155,6 +155,10 @@ struct config {
|
||||||
|
|
||||||
uint16_t resize_delay_ms;
|
uint16_t resize_delay_ms;
|
||||||
|
|
||||||
|
struct {
|
||||||
|
float amount;
|
||||||
|
} dim;
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
bool enabled;
|
bool enabled;
|
||||||
bool palette_based;
|
bool palette_based;
|
||||||
|
|
|
||||||
|
|
@ -396,7 +396,7 @@ empty string to be set, but it must be quoted: *KEY=""*)
|
||||||
*bold-text-in-bright*
|
*bold-text-in-bright*
|
||||||
Semi-boolean. When enabled, bold text is rendered in a brighter
|
Semi-boolean. When enabled, bold text is rendered in a brighter
|
||||||
color (in addition to using a bold font). The color is brightened
|
color (in addition to using a bold font). The color is brightened
|
||||||
by increasing its luminance.
|
by blending it with white.
|
||||||
|
|
||||||
If set to *palette-based*, rather than a simple *yes|true*, colors
|
If set to *palette-based*, rather than a simple *yes|true*, colors
|
||||||
matching one of the 8 regular palette colors will be brightened
|
matching one of the 8 regular palette colors will be brightened
|
||||||
|
|
@ -986,8 +986,8 @@ can configure the background transparency with the _alpha_ option.
|
||||||
an entry in the color palette. Applications emit them by combining
|
an entry in the color palette. Applications emit them by combining
|
||||||
a color value, and a "dim" attribute.
|
a color value, and a "dim" attribute.
|
||||||
|
|
||||||
By default, foot implements this by reducing the luminance of the
|
By default, foot implements this by blending the current color
|
||||||
current color. This is a generic approach that applies to both
|
with black. This is a generic approach that applies to both
|
||||||
colors from the 256-color palette, as well as 24-bit RGB colors.
|
colors from the 256-color palette, as well as 24-bit RGB colors.
|
||||||
|
|
||||||
You can change this behavior by setting the *dimN* options. When
|
You can change this behavior by setting the *dimN* options. When
|
||||||
|
|
@ -999,7 +999,7 @@ can configure the background transparency with the _alpha_ option.
|
||||||
the corresponding *regularN* color will be used.
|
the corresponding *regularN* color will be used.
|
||||||
|
|
||||||
If the current color does not match any known color, it is dimmed
|
If the current color does not match any known color, it is dimmed
|
||||||
by reducing the luminance (i.e. the same behavior as if the *dimN*
|
by blending with black (i.e. the same behavior as if the *dimN*
|
||||||
options are unconfigured). 24-bit RGB colors will typically fall
|
options are unconfigured). 24-bit RGB colors will typically fall
|
||||||
into this category.
|
into this category.
|
||||||
|
|
||||||
|
|
@ -1940,6 +1940,9 @@ any of these options.
|
||||||
Boolean. When enabled, foot will process sixel images. Default:
|
Boolean. When enabled, foot will process sixel images. Default:
|
||||||
_yes_
|
_yes_
|
||||||
|
|
||||||
|
*dim-amount*
|
||||||
|
Amount by which dimmed text is darkened. Default: _1.5_.
|
||||||
|
|
||||||
*bold-text-in-bright-amount*
|
*bold-text-in-bright-amount*
|
||||||
Amount by which bold fonts are brightened when
|
Amount by which bold fonts are brightened when
|
||||||
*bold-text-in-bright* is set to *yes* (the *palette-based* variant
|
*bold-text-in-bright* is set to *yes* (the *palette-based* variant
|
||||||
|
|
|
||||||
35
hsl.c
35
hsl.c
|
|
@ -2,41 +2,6 @@
|
||||||
|
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
|
||||||
#include "util.h"
|
|
||||||
|
|
||||||
void
|
|
||||||
rgb_to_hsl(uint32_t rgb, int *hue, int *sat, int *lum)
|
|
||||||
{
|
|
||||||
double r = (double)((rgb >> 16) & 0xff) / 255.;
|
|
||||||
double g = (double)((rgb >> 8) & 0xff) / 255.;
|
|
||||||
double b = (double)((rgb >> 0) & 0xff) / 255.;
|
|
||||||
|
|
||||||
double x_max = max(max(r, g), b);
|
|
||||||
double x_min = min(min(r, g), b);
|
|
||||||
double V = x_max;
|
|
||||||
|
|
||||||
double C = x_max - x_min;
|
|
||||||
double L = (x_max + x_min) / 2.;
|
|
||||||
|
|
||||||
*lum = 100 * L;
|
|
||||||
|
|
||||||
if (C == 0.0)
|
|
||||||
*hue = 0;
|
|
||||||
else if (V == r)
|
|
||||||
*hue = 60. * (0. + (g - b) / C);
|
|
||||||
else if (V == g)
|
|
||||||
*hue = 60. * (2. + (b - r) / C);
|
|
||||||
else if (V == b)
|
|
||||||
*hue = 60. * (4. + (r - g) / C);
|
|
||||||
if (*hue < 0)
|
|
||||||
*hue += 360;
|
|
||||||
|
|
||||||
double S = C == 0.0
|
|
||||||
? 0
|
|
||||||
: C / (1. - fabs(2. * L - 1.));
|
|
||||||
*sat = 100 * S;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t
|
uint32_t
|
||||||
hsl_to_rgb(int hue, int sat, int lum)
|
hsl_to_rgb(int hue, int sat, int lum)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
1
hsl.h
1
hsl.h
|
|
@ -2,5 +2,4 @@
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
void rgb_to_hsl(uint32_t rgb, int *hue, int *sat, int *lum);
|
|
||||||
uint32_t hsl_to_rgb(int hue, int sat, int lum);
|
uint32_t hsl_to_rgb(int hue, int sat, int lum);
|
||||||
|
|
|
||||||
56
render.c
56
render.c
|
|
@ -34,7 +34,6 @@
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include "cursor-shape.h"
|
#include "cursor-shape.h"
|
||||||
#include "grid.h"
|
#include "grid.h"
|
||||||
#include "hsl.h"
|
|
||||||
#include "ime.h"
|
#include "ime.h"
|
||||||
#include "quirks.h"
|
#include "quirks.h"
|
||||||
#include "search.h"
|
#include "search.h"
|
||||||
|
|
@ -271,13 +270,23 @@ color_hex_to_pixman(uint32_t color, bool srgb)
|
||||||
return color_hex_to_pixman_with_alpha(color, 0xffff, srgb);
|
return color_hex_to_pixman_with_alpha(color, 0xffff, srgb);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline int i_lerp(int from, int to, float t) {
|
||||||
|
return from + (to - from) * t;
|
||||||
|
}
|
||||||
|
|
||||||
static inline uint32_t
|
static inline uint32_t
|
||||||
color_decrease_luminance(uint32_t color)
|
color_blend_towards(uint32_t from, uint32_t to, float amount)
|
||||||
{
|
{
|
||||||
uint32_t alpha = color & 0xff000000;
|
if (unlikely(amount == 0))
|
||||||
int hue, sat, lum;
|
return from;
|
||||||
rgb_to_hsl(color, &hue, &sat, &lum);
|
float t = 1 - 1/amount;
|
||||||
return alpha | hsl_to_rgb(hue, sat, lum / 1.5);
|
|
||||||
|
uint32_t alpha = from & 0xff000000;
|
||||||
|
uint8_t r = i_lerp((from>>16)&0xff, (to>>16)&0xff, t);
|
||||||
|
uint8_t g = i_lerp((from>>8)&0xff, (to>>8)&0xff, t);
|
||||||
|
uint8_t b = i_lerp((from>>0)&0xff, (to>>0)&0xff, t);
|
||||||
|
|
||||||
|
return alpha | (r<<16) | (g<<8) | (b<<0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline uint32_t
|
static inline uint32_t
|
||||||
|
|
@ -286,25 +295,24 @@ color_dim(const struct terminal *term, uint32_t color)
|
||||||
const struct config *conf = term->conf;
|
const struct config *conf = term->conf;
|
||||||
const uint8_t custom_dim = conf->colors.use_custom.dim;
|
const uint8_t custom_dim = conf->colors.use_custom.dim;
|
||||||
|
|
||||||
if (likely(custom_dim == 0))
|
if (unlikely(custom_dim != 0)) {
|
||||||
return color_decrease_luminance(color);
|
for (size_t i = 0; i < 8; i++) {
|
||||||
|
if (((custom_dim >> i) & 1) == 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
for (size_t i = 0; i < 8; i++) {
|
if (term->colors.table[0 + i] == color) {
|
||||||
if (((custom_dim >> i) & 1) == 0)
|
/* "Regular" color, return the corresponding "dim" */
|
||||||
continue;
|
return conf->colors.dim[i];
|
||||||
|
}
|
||||||
|
|
||||||
if (term->colors.table[0 + i] == color) {
|
else if (term->colors.table[8 + i] == color) {
|
||||||
/* "Regular" color, return the corresponding "dim" */
|
/* "Bright" color, return the corresponding "regular" */
|
||||||
return conf->colors.dim[i];
|
return term->colors.table[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (term->colors.table[8 + i] == color) {
|
|
||||||
/* "Bright" color, return the corresponding "regular" */
|
|
||||||
return term->colors.table[i];
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return color_decrease_luminance(color);
|
return color_blend_towards(color, 0x00000000, conf->dim.amount);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline uint32_t
|
static inline uint32_t
|
||||||
|
|
@ -322,11 +330,7 @@ color_brighten(const struct terminal *term, uint32_t color)
|
||||||
return color;
|
return color;
|
||||||
}
|
}
|
||||||
|
|
||||||
int hue, sat, lum;
|
return color_blend_towards(color, 0x00ffffff, term->conf->bold_in_bright.amount);
|
||||||
rgb_to_hsl(color, &hue, &sat, &lum);
|
|
||||||
|
|
||||||
lum = (int)roundf(lum * term->conf->bold_in_bright.amount);
|
|
||||||
return hsl_to_rgb(hue, sat, min(lum, 100));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
|
@ -798,7 +802,7 @@ render_cell(struct terminal *term, pixman_image_t *pix,
|
||||||
_fg = color_brighten(term, _fg);
|
_fg = color_brighten(term, _fg);
|
||||||
|
|
||||||
if (cell->attrs.blink && term->blink.state == BLINK_OFF)
|
if (cell->attrs.blink && term->blink.state == BLINK_OFF)
|
||||||
_fg = color_decrease_luminance(_fg);
|
_fg = color_blend_towards(_fg, 0x00000000, term->conf->dim.amount);
|
||||||
|
|
||||||
const bool gamma_correct = render_do_linear_blending(term);
|
const bool gamma_correct = render_do_linear_blending(term);
|
||||||
pixman_color_t fg = color_hex_to_pixman(_fg, gamma_correct);
|
pixman_color_t fg = color_hex_to_pixman(_fg, gamma_correct);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue