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
|
||||
|
||||
* 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
|
||||
|
|
|
|||
4
config.c
4
config.c
|
|
@ -2759,6 +2759,9 @@ parse_section_tweak(struct context *ctx)
|
|||
else if (streq(key, "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"))
|
||||
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_keep_grid = true,
|
||||
.resize_delay_ms = 100,
|
||||
.dim = { .amount = 1.5 },
|
||||
.bold_in_bright = {
|
||||
.enabled = false,
|
||||
.palette_based = false,
|
||||
|
|
|
|||
4
config.h
4
config.h
|
|
@ -155,6 +155,10 @@ struct config {
|
|||
|
||||
uint16_t resize_delay_ms;
|
||||
|
||||
struct {
|
||||
float amount;
|
||||
} dim;
|
||||
|
||||
struct {
|
||||
bool enabled;
|
||||
bool palette_based;
|
||||
|
|
|
|||
|
|
@ -396,7 +396,7 @@ empty string to be set, but it must be quoted: *KEY=""*)
|
|||
*bold-text-in-bright*
|
||||
Semi-boolean. When enabled, bold text is rendered in a brighter
|
||||
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
|
||||
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
|
||||
a color value, and a "dim" attribute.
|
||||
|
||||
By default, foot implements this by reducing the luminance of the
|
||||
current color. This is a generic approach that applies to both
|
||||
By default, foot implements this by blending the current color
|
||||
with black. This is a generic approach that applies to both
|
||||
colors from the 256-color palette, as well as 24-bit RGB colors.
|
||||
|
||||
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.
|
||||
|
||||
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
|
||||
into this category.
|
||||
|
||||
|
|
@ -1940,6 +1940,9 @@ any of these options.
|
|||
Boolean. When enabled, foot will process sixel images. Default:
|
||||
_yes_
|
||||
|
||||
*dim-amount*
|
||||
Amount by which dimmed text is darkened. Default: _1.5_.
|
||||
|
||||
*bold-text-in-bright-amount*
|
||||
Amount by which bold fonts are brightened when
|
||||
*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 "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
|
||||
hsl_to_rgb(int hue, int sat, int lum)
|
||||
{
|
||||
|
|
|
|||
1
hsl.h
1
hsl.h
|
|
@ -2,5 +2,4 @@
|
|||
|
||||
#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);
|
||||
|
|
|
|||
56
render.c
56
render.c
|
|
@ -34,7 +34,6 @@
|
|||
#include "config.h"
|
||||
#include "cursor-shape.h"
|
||||
#include "grid.h"
|
||||
#include "hsl.h"
|
||||
#include "ime.h"
|
||||
#include "quirks.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);
|
||||
}
|
||||
|
||||
static inline int i_lerp(int from, int to, float t) {
|
||||
return from + (to - from) * 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;
|
||||
int hue, sat, lum;
|
||||
rgb_to_hsl(color, &hue, &sat, &lum);
|
||||
return alpha | hsl_to_rgb(hue, sat, lum / 1.5);
|
||||
if (unlikely(amount == 0))
|
||||
return from;
|
||||
float t = 1 - 1/amount;
|
||||
|
||||
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
|
||||
|
|
@ -286,25 +295,24 @@ color_dim(const struct terminal *term, uint32_t color)
|
|||
const struct config *conf = term->conf;
|
||||
const uint8_t custom_dim = conf->colors.use_custom.dim;
|
||||
|
||||
if (likely(custom_dim == 0))
|
||||
return color_decrease_luminance(color);
|
||||
if (unlikely(custom_dim != 0)) {
|
||||
for (size_t i = 0; i < 8; i++) {
|
||||
if (((custom_dim >> i) & 1) == 0)
|
||||
continue;
|
||||
|
||||
for (size_t i = 0; i < 8; i++) {
|
||||
if (((custom_dim >> i) & 1) == 0)
|
||||
continue;
|
||||
if (term->colors.table[0 + i] == color) {
|
||||
/* "Regular" color, return the corresponding "dim" */
|
||||
return conf->colors.dim[i];
|
||||
}
|
||||
|
||||
if (term->colors.table[0 + i] == color) {
|
||||
/* "Regular" color, return the corresponding "dim" */
|
||||
return conf->colors.dim[i];
|
||||
}
|
||||
|
||||
else if (term->colors.table[8 + i] == color) {
|
||||
/* "Bright" color, return the corresponding "regular" */
|
||||
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
|
||||
|
|
@ -322,11 +330,7 @@ color_brighten(const struct terminal *term, uint32_t color)
|
|||
return color;
|
||||
}
|
||||
|
||||
int hue, sat, lum;
|
||||
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));
|
||||
return color_blend_towards(color, 0x00ffffff, term->conf->bold_in_bright.amount);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -798,7 +802,7 @@ render_cell(struct terminal *term, pixman_image_t *pix,
|
|||
_fg = color_brighten(term, _fg);
|
||||
|
||||
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);
|
||||
pixman_color_t fg = color_hex_to_pixman(_fg, gamma_correct);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue