Skip to content

Instantly share code, notes, and snippets.

@N-R-K
Last active March 26, 2022 09:48
Show Gist options
  • Save N-R-K/469d5888d889fa35fb807040abbcf80d to your computer and use it in GitHub Desktop.
Save N-R-K/469d5888d889fa35fb807040abbcf80d to your computer and use it in GitHub Desktop.
dmenu/dwm patch: color gradient
From 94132cbde161398b51cded896aa5989d0a96e563 Mon Sep 17 00:00:00 2001
From: NRK <nrk@disroot.org>
Date: Sat, 26 Mar 2022 03:06:36 +0600
Subject: [PATCH] patch: add color gradient
this patch uses HSL color representation and changes the hue +1 for each
w pixel. probably not very efficient drawing things one column at a time.
caveat: assumes true-color X server which supports rgb colors.
---
drw.c | 80 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++--
1 file changed, 78 insertions(+), 2 deletions(-)
diff --git a/drw.c b/drw.c
index a50c9ee..850a1d0 100644
--- a/drw.c
+++ b/drw.c
@@ -4,6 +4,7 @@
#include <string.h>
#include <X11/Xlib.h>
#include <X11/Xft/Xft.h>
+#include <limits.h>
#include "drw.h"
#include "util.h"
@@ -16,6 +17,32 @@ static const unsigned char utfmask[UTF_SIZ + 1] = {0xC0, 0x80, 0xE0, 0xF0, 0xF8}
static const long utfmin[UTF_SIZ + 1] = { 0, 0, 0x80, 0x800, 0x10000};
static const long utfmax[UTF_SIZ + 1] = {0x10FFFF, 0x7F, 0x7FF, 0xFFFF, 0x10FFFF};
+typedef unsigned short ushort;
+typedef unsigned long ulong;
+typedef unsigned int uint;
+#if UINT_MAX == 4294967295UL
+ typedef signed int i32;
+ typedef unsigned int u32;
+ #define U32_X_FMT "X"
+#elif ULONG_MAX == 4294967295UL
+ typedef signed long i32;
+ typedef unsigned long u32;
+ #define U32_X_FMT "lX"
+#else
+ #error "32 bit not available"
+#endif
+
+#define R(X) (((X) & 0xFF0000) >> 16)
+#define G(X) (((X) & 0x00FF00) >> 8)
+#define B(X) (((X) & 0x0000FF) >> 0)
+
+typedef struct {
+ ushort h : 9;
+ ushort s : 7;
+ ushort l : 7;
+ ushort idx : 9;
+} HSL;
+
static long
utf8decodebyte(const char c, size_t *i)
{
@@ -248,6 +275,49 @@ drw_rect(Drw *drw, int x, int y, unsigned int w, unsigned int h, int filled, int
XDrawRectangle(drw->dpy, drw->drawable, drw->gc, x, y, w - 1, h - 1);
}
+static u32
+hsl_to_rgb(HSL col)
+{
+ ulong f, p, q, t;
+ ulong h, s, l;
+ ulong r, g, b;
+
+ if (col.s == 0) {
+ const u32 tmp = (col.l * 255) / 100;
+ return (tmp << 16) | (tmp << 8) | tmp;
+ }
+
+ h = (col.h * 1000) / 6;
+ s = col.s;
+ l = col.l;
+
+ f = (h % 10000) / 100;
+ p = l * (100 - s);
+ q = l * (100 - (s * f) / 100);
+ t = (l * (10000 - s * (100 - f))) / 100;
+
+ l *= 100; /* scaled up x10000 */
+
+ switch (h/10000) {
+ case 0:
+ r = l; g = t; b = p; break;
+ case 1:
+ r = q; g = l; b = p; break;
+ case 2:
+ r = p; g = l; b = t; break;
+ case 3:
+ r = p; g = q; b = l; break;
+ case 4:
+ r = t; g = p; b = l; break;
+ default:
+ r = l; g = p; b = q; break;
+ }
+
+ return (((r * 255) / 10000) << 16) |
+ (((g * 255) / 10000) << 8) |
+ (((b * 255) / 10000) << 0);
+}
+
int
drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, unsigned int lpad, const char *text, int invert)
{
@@ -273,8 +343,14 @@ drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, unsigned int lp
if (!render) {
w = invert ? invert : ~invert;
} else {
- XSetForeground(drw->dpy, drw->gc, drw->scheme[invert ? ColFg : ColBg].pixel);
- XFillRectangle(drw->dpy, drw->drawable, drw->gc, x, y, w, h);
+ static HSL col = { 0, 50, 50, 0 };
+ if (x < 10)
+ col.h = 0;
+ for (i = 0; i < w; ++i) {
+ col.h = (col.h + 1) % 360;
+ XSetForeground(drw->dpy, drw->gc, hsl_to_rgb(col));
+ XFillRectangle(drw->dpy, drw->drawable, drw->gc, x+i, y, 1, h);
+ }
d = XftDrawCreate(drw->dpy, drw->drawable,
DefaultVisual(drw->dpy, drw->screen),
DefaultColormap(drw->dpy, drw->screen));
--
2.34.1
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment