Introduction
Introduction Statistics Contact Development Disclaimer Help
st-minimumcontrast-20241029-0.9.2.diff - sites - public wiki contents of suckle…
git clone git://git.suckless.org/sites
Log
Files
Refs
---
st-minimumcontrast-20241029-0.9.2.diff (5744B)
---
1 From b0601465dc4d654485db7c3bcb28e019b21e78ca Mon Sep 17 00:00:00 2001
2 From: Nick Lott <[email protected]>
3 Date: Sun, 13 Oct 2024 11:14:38 +1300
4 Subject: [PATCH] Add minimum contrast ratio feature
5
6 ---
7 Makefile | 2 +-
8 config.def.h | 6 +++
9 contrast.c | 146 +++++++++++++++++++++++++++++++++++++++++++++++++++
10 contrast.h | 11 ++++
11 x.c | 12 +++++
12 5 files changed, 176 insertions(+), 1 deletion(-)
13 create mode 100644 contrast.c
14 create mode 100644 contrast.h
15
16 diff --git a/Makefile b/Makefile
17 index 15db421..893c71b 100644
18 --- a/Makefile
19 +++ b/Makefile
20 @@ -4,7 +4,7 @@
21
22 include config.mk
23
24 -SRC = st.c x.c
25 +SRC = st.c x.c contrast.c
26 OBJ = $(SRC:.c=.o)
27
28 all: st
29 diff --git a/config.def.h b/config.def.h
30 index 2cd740a..03eed3a 100644
31 --- a/config.def.h
32 +++ b/config.def.h
33 @@ -134,6 +134,12 @@ unsigned int defaultbg = 259;
34 unsigned int defaultcs = 256;
35 static unsigned int defaultrcs = 257;
36
37 +
38 +/*
39 +* Minimum contrast ratio (1-21)
40 +*/
41 +const float min_contrast_ratio = 2.2f;
42 +
43 /*
44 * Default shape of cursor
45 * 2: Block ("█")
46 diff --git a/contrast.c b/contrast.c
47 new file mode 100644
48 index 0000000..d956bd6
49 --- /dev/null
50 +++ b/contrast.c
51 @@ -0,0 +1,146 @@
52 +#include <math.h>
53 +
54 +#include "contrast.h"
55 +
56 +
57 +/* Linear RGB floating point color space for use in calculations */
58 +typedef struct {
59 + float r;
60 + float g;
61 + float b;
62 + float l;
63 +} RGBf;
64 +
65 +
66 +
67 +static float
68 +sRGB_to_lin(const unsigned short c)
69 +{
70 + /* Convert to normalized float. */
71 + const float f = c / 65535.0f;
72 +
73 + /* Convert from sRGB to linear space. */
74 + return (f <= 0.03928f) ? f / 12.92f : pow((f + 0.055f) / 1.055f…
75 +}
76 +
77 +
78 +
79 +static unsigned short
80 +lin_to_sRGB(const float c)
81 +{
82 + /* Convert to sRGB space. */
83 + const float f = (c <= 0.0031308f) ?
84 + 12.92f * c : 1.055f * pow(c, 1.0f / 2.4f)…
85 +
86 + /* Clamp and convert back to 16-bit values. */
87 + return (unsigned short)(fminf(fmaxf(f * 65535.0f, 0.0f),…
88 +}
89 +
90 +
91 +
92 +static RGBf
93 +XftColor_to_RGBf( XftColor const * const c )
94 +{
95 + const float r = sRGB_to_lin(c->color.red);
96 + const float g = sRGB_to_lin(c->color.green);
97 + const float b = sRGB_to_lin(c->color.blue);
98 +
99 + /* Calculate luminance. */
100 + const float l = 0.2126f * r + 0.7152f * g + 0.0722f * b;
101 +
102 + return (RGBf) {r, g, b, l};
103 +}
104 +
105 +
106 +
107 +static void
108 +RGBf_to_XftColor( const RGBf rgb, XftColor * const c)
109 +{
110 + c->color.red = lin_to_sRGB(rgb.r);
111 + c->color.green = lin_to_sRGB(rgb.g);
112 + c->color.blue = lin_to_sRGB(rgb.b);
113 +}
114 +
115 +
116 +
117 +static float
118 +get_luminance(XftColor const * const c)
119 +{
120 + const RGBf rgb = XftColor_to_RGBf(c);
121 + return rgb.l;
122 +}
123 +
124 +
125 +
126 +static float
127 +get_contrast_ratio(const float fg_lum, const float bg_lum)
128 +{
129 + if (fg_lum > bg_lum) {
130 + return (fg_lum + 0.05f) / (bg_lum + 0.05f);
131 + } else {
132 + return (bg_lum + 0.05f) / (fg_lum + 0.05f);
133 + }
134 +}
135 +
136 +
137 +
138 +static void
139 +adjust_luminance(XftColor * const c, const float adjustment)
140 +{
141 + /* Convert sRGB to linear space and calculate luminance. */
142 + RGBf rgb = XftColor_to_RGBf(c);
143 +
144 + /* Adjust luminance, clamping to 0-100% */
145 + const float factor = fminf(fmaxf(rgb.l + adjustment, 0.0f), 1.0…
146 + rgb.r *= factor;
147 + rgb.g *= factor;
148 + rgb.b *= factor;
149 +
150 + /* Convert back to sRGB space. */
151 + RGBf_to_XftColor(rgb, c);
152 +}
153 +
154 +
155 +static float
156 +get_luminance_adjustment( float fl, float bl, float contrast )
157 +{
158 + /* Increase existing any luminance difference to get contrast. …
159 + float adjustment = (bl > fl)?
160 + ((((bl + 0.05f) / min_contrast_ratio) - 0.05f) - fl) :
161 + (((min_contrast_ratio * (bl + 0.05f)) - 0.05f) - fl);
162 +
163 + const float new_lum = fl + adjustment;
164 +
165 + /* Use the opposite direction if we exceed valid luminance rang…
166 + if (new_lum < 0.0 || new_lum > 1.0) {
167 + adjustment = (bl <= fl)?
168 + ((((bl + 0.05f) / min_contrast_ratio) - 0.05f) - fl…
169 + (((min_contrast_ratio * (bl + 0.05f)) - 0.05f) - fl…
170 + }
171 +
172 + return adjustment;
173 +}
174 +
175 +
176 +void
177 +adjust_color_for_contrast(XftColor * const fg, XftColor * const bg)
178 +{
179 + float fl = get_luminance(fg);
180 + const float bl = get_luminance(bg);
181 + const float contrast = get_contrast_ratio(fl, bl);
182 +
183 + if (contrast < min_contrast_ratio) {
184 + /* Change black to dark grey so the luminance calculati…
185 + if (fl < 0.00001) {
186 + fg->color.red = 0x1fff;
187 + fg->color.green = 0x1fff;
188 + fg->color.blue = 0x1fff;
189 + fl = get_luminance(fg);
190 + }
191 +
192 + const float adjustment = get_luminance_adjustment(
193 + fl, bl, min_contrast_ratio…
194 +
195 + adjust_luminance(fg, adjustment);
196 + }
197 +}
198 diff --git a/contrast.h b/contrast.h
199 new file mode 100644
200 index 0000000..2aa6dd3
201 --- /dev/null
202 +++ b/contrast.h
203 @@ -0,0 +1,11 @@
204 +#ifndef __ST_CONTRAST_H_
205 +#define __ST_CONTRAST_H_
206 +
207 +#include <X11/Xft/Xft.h>
208 +
209 +void adjust_color_for_contrast(XftColor * const , XftColor * const );
210 +
211 +/* config.h globals */
212 +extern const float min_contrast_ratio;
213 +
214 +#endif
215 diff --git a/x.c b/x.c
216 index bd23686..4c79e52 100644
217 --- a/x.c
218 +++ b/x.c
219 @@ -19,6 +19,7 @@ char *argv0;
220 #include "arg.h"
221 #include "st.h"
222 #include "win.h"
223 +#include "contrast.h"
224
225 /* types used in config.h */
226 typedef struct {
227 @@ -1478,6 +1479,17 @@ xdrawglyphfontspecs(const XftGlyphFontSpec *specs…
228 if (winy + win.ch >= borderpx + win.th)
229 xclear(winx, winy + win.ch, winx + width, win.h);
230
231 +
232 + /*
233 + * Adjust colours to enforce a minimum contrast. Using the loca…
234 + * here to ensure we don't alter the dc.cols table permanently.
235 + */
236 + fg = memcpy( &truefg, fg, sizeof(Color));
237 + bg = memcpy( &truebg, bg, sizeof(Color));
238 +
239 + adjust_color_for_contrast( fg, bg);
240 +
241 +
242 /* Clean up the region we want to draw to. */
243 XftDrawRect(xw.draw, bg, winx, winy, width, win.ch);
244
245 --
246 2.34.1
247
You are viewing proxied material from suckless.org. The copyright of proxied material belongs to its original authors. Any comments or complaints in relation to proxied material should be directed to the original authors of the content concerned. Please see the disclaimer for more details.