--- rxvt-unicode/src/rxvtimg.C 2012/06/09 11:15:29 1.69 +++ rxvt-unicode/src/rxvtimg.C 2012/06/09 19:20:04 1.74 @@ -51,6 +51,7 @@ return img; } +# if HAVE_PIXBUF rxvt_img * rxvt_img::new_from_pixbuf (rxvt_screen *s, GdkPixbuf *pb) { @@ -168,6 +169,7 @@ return img; } +# endif void rxvt_img::destroy () @@ -323,7 +325,7 @@ XRenderPictFormat *format = XRenderFindStandardFormat (dpy, argb ? PictStandardARGB32 : PictStandardA8); XRenderPictureAttributes pa; - pa.repeat = True; + pa.repeat = RepeatNormal; Picture mask = XRenderCreatePicture (dpy, pixmap, format, CPRepeat, &pa); XFreePixmap (dpy, pixmap); @@ -359,8 +361,7 @@ Picture dst = XRenderCreatePicture (dpy, pm, format, 0, 0); // loop should not be needed for brightness, as only -1..1 makes sense - - while (r | g | b | a) + //while (r | g | b | a) { unsigned short xr, xg, xb, xa; XRenderColor mask_c; @@ -372,7 +373,7 @@ { XRenderColor mask_w = { 65535, 65535, 65535, 65535 }; XRenderFillRectangle (dpy, PictOpDifference, dst, &mask_w, 0, 0, w, h); - mask_c.red = -mask_c.red; + mask_c.red = -mask_c.red; //TODO: verify that doing clamp, assign, and negation does the right thing mask_c.green = -mask_c.green; mask_c.blue = -mask_c.blue; mask_c.alpha = -mask_c.alpha; @@ -381,36 +382,60 @@ } } - XRenderFreePicture (dpy, dst); } void rxvt_img::contrast (int32_t r, int32_t g, int32_t b, int32_t a) { - if (!(s->display->flags & DISPLAY_HAS_RENDER_MUL)) - { - rxvt_warn ("rxvt_img::contrast operation not supported on this display, RENDER extension too old.\n"); - return; - } + if (r < 0 || g < 0 || b < 0 || a < 0) + rxvt_fatal ("rxvt_img::contrast does not support negative values.\n"); - unshare (); + rxvt_img *img = new rxvt_img (s, format, x, y, w, h, repeat); + img->alloc (); + + { + rxvt_color empty; + empty.set (s, rgba (0, 0, 0, 0)); + img->fill (empty); + } + + // premultiply (yeah, these are not exact, sue me or fix it) + r = (r * (a >> 8)) >> 8; + g = (g * (a >> 8)) >> 8; + b = (b * (a >> 8)) >> 8; Display *dpy = s->display->dpy; - Picture src = create_xrender_mask (dpy, pm, True); - Picture dst = XRenderCreatePicture (dpy, pm, format, 0, 0); - XRenderColor mask_c; - mask_c.red = r; - mask_c.green = g; - mask_c.blue = b; - mask_c.alpha = a; - XRenderFillRectangle (dpy, PictOpSrc, src, &mask_c, 0, 0, 1, 1); + Picture src = src_picture (); + Picture dst = XRenderCreatePicture (dpy, img->pm, format, 0, 0); + Picture mul = create_xrender_mask (dpy, pm, True); - XRenderComposite (dpy, PictOpMultiply, src, None, dst, 0, 0, 0, 0, 0, 0, w, h); + XRenderPictureAttributes pa; + pa.component_alpha = 1; + XRenderChangePicture (dpy, mul, CPComponentAlpha, &pa); - XRenderFreePicture (dpy, src); + //TODO: this operator does not yet implement some useful contrast + while (r | g | b | a) + { + unsigned short xr, xg, xb, xa; + XRenderColor mask_c; + + if (extract (0, 65535, r, g, b, a, mask_c.red, mask_c.green, mask_c.blue, mask_c.alpha)) + { + XRenderFillRectangle (dpy, PictOpSrc, mul, &mask_c, 0, 0, 1, 1); + XRenderComposite (dpy, PictOpAdd, src, mul, dst, 0, 0, 0, 0, 0, 0, w, h); + } + } + + XRenderFreePicture (dpy, mul); XRenderFreePicture (dpy, dst); + XRenderFreePicture (dpy, src); + + ::swap (img->ref, ref); + ::swap (img->pm , pm ); + + delete img; } rxvt_img * @@ -602,7 +627,13 @@ Display *dpy = s->display->dpy; Picture src = img->src_picture (); Picture dst = XRenderCreatePicture (dpy, img2->pm, img2->format, 0, 0); - Picture mask = create_xrender_mask (dpy, img->pm, False); + + Pixmap pixmap = XCreatePixmap (dpy, img->pm, 1, 1, 8); + XRenderPictFormat *format = XRenderFindStandardFormat (dpy, PictStandardA8); + XRenderPictureAttributes pa; + pa.repeat = True; + Picture mask = XRenderCreatePicture (dpy, pixmap, format, CPRepeat, &pa); + XFreePixmap (dpy, pixmap); XRenderColor mask_c;