Skip to content

Commit 09e457b

Browse files
committed
premultiply alpha
1 parent cbd81e2 commit 09e457b

File tree

2 files changed

+26
-18
lines changed

2 files changed

+26
-18
lines changed

drw.c

+9-10
Original file line numberDiff line numberDiff line change
@@ -379,25 +379,24 @@ drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, unsigned int lp
379379
return x + (render ? w : 0);
380380
}
381381

382-
static uint32_t blend32(uint32_t p1, uint32_t p2) {
383-
uint32_t a = p2 >> 24;
384-
uint32_t na = 255 - a;
385-
uint32_t rb = ((na * (p1 & 0x00ff00ffu)) + (a * (p2 & 0x00ff00ffu))) >> 8;
386-
uint32_t ag = (na * ((p1 & 0xff00ff00u) >> 8)) + (a * (0x01000000u | ((p2 & 0x0000ff00u) >> 8)));
387-
return ((rb & 0x00ff00ffu) | (ag & 0xff00ff00u));
382+
static uint32_t blend(uint32_t p1rb, uint32_t p1g, uint32_t p2) {
383+
uint8_t a = p2 >> 24u;
384+
uint32_t rb = (p2 & 0xFF00FFu) + ( (a * p1rb) >> 8u );
385+
uint32_t g = (p2 & 0x00FF00u) + ( (a * p1g) >> 8u );
386+
return (rb & 0xFF00FFu) | (g & 0x00FF00u);
388387
}
389388

390389
void
391390
drw_img(Drw *drw, int x, int y, XImage *img, uint32_t *tmp)
392391
{
393392
if (!drw || !drw->scheme)
394393
return;
395-
uint32_t *data = (uint32_t *)img->data, bt = drw->scheme[ColBg].pixel;
394+
uint32_t *data = (uint32_t *)img->data, p = drw->scheme[ColBg].pixel, prb = p & 0xFF00FFu, pg = p & 0x00FF00u;
396395
int icsz = img->width * img->height, i;
397-
for (i = 0; i < icsz; ++i) tmp[i] = blend32(bt, data[i]);
398-
img->data = (char *)tmp;
396+
for (i = 0; i < icsz; ++i) tmp[i] = blend(prb, pg, data[i]);
397+
img->data = (char *) tmp;
399398
XPutImage(drw->dpy, drw->drawable, drw->gc, img, 0, 0, x, y, img->width, img->height);
400-
img->data = (char *)data;
399+
img->data = (char *) data;
401400
}
402401

403402
void

dwm.c

+17-8
Original file line numberDiff line numberDiff line change
@@ -908,6 +908,13 @@ getstate(Window w)
908908
return result;
909909
}
910910

911+
static uint32_t prealpha(uint32_t p) {
912+
uint8_t a = p >> 24u;
913+
uint32_t rb = (a * (p & 0xFF00FFu)) >> 8u;
914+
uint32_t g = (a * (p & 0x00FF00u)) >> 8u;
915+
return (rb & 0xFF00FFu) | (g & 0x00FF00u) | ((~a) << 24u);
916+
}
917+
911918
XImage *
912919
geticonprop(Window win)
913920
{
@@ -945,7 +952,7 @@ geticonprop(Window win)
945952

946953
w = *(bstp - 2); h = *(bstp - 1);
947954

948-
int icw, ich;
955+
int icw, ich, icsz;
949956
if (w <= h) {
950957
ich = ICONSIZE; icw = w * ICONSIZE / h;
951958
if (icw < 1) icw = 1;
@@ -954,29 +961,31 @@ geticonprop(Window win)
954961
icw = ICONSIZE; ich = h * ICONSIZE / w;
955962
if (ich < 1) ich = 1;
956963
}
964+
icsz = icw * ich;
957965

958-
unsigned char *icbuf = malloc(icw * ich << 2); if(!icbuf) { XFree(p); return NULL; }
966+
int i;
959967
#if ULONG_MAX > UINT32_MAX
960-
int i, sz = w * h;
968+
int sz = w * h;
961969
uint32_t *bstp32 = (uint32_t *)bstp;
962970
for (i = 0; i < sz; ++i) bstp32[i] = bstp[i];
963971
#endif
964-
if (w == icw && h == ich) memcpy(icbuf, bstp, icw * ich << 2);
972+
uint32_t *icbuf = malloc(icsz << 2); if(!icbuf) { XFree(p); return NULL; }
973+
if (w == icw && h == ich) memcpy(icbuf, bstp, icsz << 2);
965974
else {
966975
Imlib_Image origin = imlib_create_image_using_data(w, h, (DATA32 *)bstp);
967-
if (!origin) { XFree(p); return NULL; }
976+
if (!origin) { XFree(p); free(icbuf); return NULL; }
968977
imlib_context_set_image(origin);
969978
imlib_image_set_has_alpha(1);
970979
Imlib_Image scaled = imlib_create_cropped_scaled_image(0, 0, w, h, icw, ich);
971980
imlib_free_image_and_decache();
972-
if (!scaled) { XFree(p); return NULL; }
981+
if (!scaled) { XFree(p); free(icbuf); return NULL; }
973982
imlib_context_set_image(scaled);
974983
imlib_image_set_has_alpha(1);
975-
memcpy(icbuf, imlib_image_get_data_for_reading_only(), icw * ich << 2);
984+
memcpy(icbuf, imlib_image_get_data_for_reading_only(), icsz << 2);
976985
imlib_free_image_and_decache();
977986
}
978987
XFree(p);
979-
988+
for (i = 0; i < icsz; ++i) icbuf[i] = prealpha(icbuf[i]);
980989
return XCreateImage(dpy, DefaultVisual(dpy, screen), DefaultDepth(dpy, screen), ZPixmap, 0, (char *)icbuf, icw, ich, 32, 0);
981990
}
982991

0 commit comments

Comments
 (0)