--- rxvt-unicode/src/rxvtimg.C 2012/07/02 03:57:53 1.101 +++ rxvt-unicode/src/rxvtimg.C 2014/05/22 18:54:33 1.107 @@ -8,7 +8,7 @@ * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or + * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, @@ -351,35 +351,28 @@ unsigned char *src = row; uint32_t *dst = (uint32_t *)line; - if (!pb_has_alpha) - for (int x = 0; x < width; x++) - { - uint8_t r = *src++; - uint8_t g = *src++; - uint8_t b = *src++; - - uint32_t v = (255 << 24) | (r << 16) | (g << 8) | b; - - if (ecb_big_endian () ? !byte_order_mismatch : byte_order_mismatch) - v = ecb_bswap32 (v); - - *dst++ = v; - } - else - for (int x = 0; x < width; x++) - { - uint32_t v = *(uint32_t *)src; src += 4; - - if (ecb_big_endian ()) - v = ecb_bswap32 (v); + for (int x = 0; x < width; x++) + { + uint8_t r = *src++; + uint8_t g = *src++; + uint8_t b = *src++; + uint8_t a = *src; + + // this is done so it can be jump-free, but newer gcc's clone inner the loop + a = pb_has_alpha ? a : 255; + src += pb_has_alpha; + + r = (r * a + 127) / 255; + g = (g * a + 127) / 255; + b = (b * a + 127) / 255; - v = ecb_rotl32 (v, 8); // abgr to bgra + uint32_t v = (a << 24) | (r << 16) | (g << 8) | b; - if (!byte_order_mismatch) - v = ecb_bswap32 (v); + if (ecb_big_endian () ? !byte_order_mismatch : byte_order_mismatch) + v = ecb_bswap32 (v); - *dst++ = v; - } + *dst++ = v; + } row += rowstride; line += xi.bytes_per_line; @@ -542,7 +535,7 @@ Display *dpy = s->dpy; int size = max (rh, rv) * 2 + 1; nv *kernel = (nv *)malloc (size * sizeof (nv)); - XFixed *params = (XFixed *)malloc ((size + 2) * sizeof (XFixed)); + XFixed *params = rxvt_temp_buf (size + 2); rxvt_img *img = new_empty (); XRenderPictureAttributes pa; @@ -587,7 +580,6 @@ } free (kernel); - free (params); XRenderFreePicture (dpy, src); XRenderFreePicture (dpy, dst); @@ -606,9 +598,9 @@ // why the hell does XRenderSetPictureTransform want a writable matrix :( // that keeps us from just static const'ing this matrix. XTransform h_double = { - 32768, 0, 0, - 0, 65536, 0, - 0, 0, 65536 + 0x08000, 0, 0, + 0, 0x10000, 0, + 0, 0, 0x10000 }; XRenderSetPictureFilter (cc.dpy, cc.src, "nearest", 0, 0); @@ -640,9 +632,9 @@ }; XTransform h_halve = { - 131072, 0, 0, - 0, 65536, 0, - 0, 0, 65536 + 0x20000, 0, 0, + 0, 0x10000, 0, + 0, 0, 0x10000 }; XRenderSetPictureFilter (cc.dpy, cc2.src, "nearest", 0, 0); @@ -767,8 +759,6 @@ if (x == 0 && y == 0 && w == ref->w && h == ref->h) return clone (); - Display *dpy = s->dpy; - // add an alpha channel if... bool alpha = !format->direct.alphaMask // pixmap has none yet && (x || y) // we need one because of non-zero offset @@ -777,7 +767,7 @@ composer cc (this, new rxvt_img (s, alpha ? find_alpha_format_for (s->dpy, format) : format, 0, 0, w, h, repeat)); - if (alpha) + if (repeat == RepeatNone) { XRenderColor rc = { 0, 0, 0, 0 }; XRenderFillRectangle (cc.dpy, PictOpSrc, cc.dst, &rc, 0, 0, w, h);//TODO: split into four fillrectangles @@ -926,6 +916,40 @@ } rxvt_img * +rxvt_img::shade (nv factor, rgba c) +{ + clamp_it (factor, -1., 1.); + factor++; + + if (factor > 1) + { + c.r = c.r * (2 - factor); + c.g = c.g * (2 - factor); + c.b = c.b * (2 - factor); + } + else + { + c.r = c.r * factor; + c.g = c.g * factor; + c.b = c.b * factor; + } + + rxvt_img *img = this->tint (c); + + if (factor > 1) + { + c.a = 0xffff; + c.r = + c.g = + c.b = 0xffff * (factor - 1); + + img->brightness (c.r, c.g, c.b, c.a); + } + + return img; +} + +rxvt_img * rxvt_img::filter (const char *name, int nparams, nv *params) { composer cc (this);