… | |
… | |
398 | } |
398 | } |
399 | |
399 | |
400 | rxvt_img * |
400 | rxvt_img * |
401 | rxvt_img::new_from_file (rxvt_screen *s, const char *filename) |
401 | rxvt_img::new_from_file (rxvt_screen *s, const char *filename) |
402 | { |
402 | { |
403 | GError *err; |
403 | GError *err = 0; |
404 | GdkPixbuf *pb = gdk_pixbuf_new_from_file (filename, &err); |
404 | GdkPixbuf *pb = gdk_pixbuf_new_from_file (filename, &err); |
405 | |
405 | |
406 | if (!pb) |
406 | if (!pb) |
407 | try |
407 | try |
408 | { |
408 | { |
… | |
… | |
606 | rxvt_img * |
606 | rxvt_img * |
607 | rxvt_img::muladd (nv mul, nv add) |
607 | rxvt_img::muladd (nv mul, nv add) |
608 | { |
608 | { |
609 | // STEP 1: double the image width, fill all odd columns with white (==1) |
609 | // STEP 1: double the image width, fill all odd columns with white (==1) |
610 | |
610 | |
611 | composer cc (this, new rxvt_img (d, format, 0, 0, w * 2, h, repeat)); |
611 | rxvt_img *img = new rxvt_img (d, format, 0, 0, w * 2, h, repeat); |
|
|
612 | composer cc (this, img); |
612 | |
613 | |
613 | // why the hell does XRenderSetPictureTransform want a writable matrix :( |
614 | // why the hell does XRenderSetPictureTransform want a writable matrix :( |
614 | // that keeps us from just static const'ing this matrix. |
615 | // that keeps us from just static const'ing this matrix. |
615 | XTransform h_double = { |
616 | XTransform h_double = { |
616 | 0x08000, 0, 0, |
617 | 0x08000, 0, 0, |
… | |
… | |
637 | |
638 | |
638 | // STEP 2: convolve the image with a 3x1 filter |
639 | // STEP 2: convolve the image with a 3x1 filter |
639 | // a 2x1 filter would obviously suffice, but given the total lack of specification |
640 | // a 2x1 filter would obviously suffice, but given the total lack of specification |
640 | // for xrender, I expect different xrender implementations to randomly diverge. |
641 | // for xrender, I expect different xrender implementations to randomly diverge. |
641 | // we also halve the image, and hope for the best (again, for lack of specs). |
642 | // we also halve the image, and hope for the best (again, for lack of specs). |
642 | composer cc2 (cc.dstimg); |
643 | composer cc2 (img); |
643 | |
644 | |
644 | XFixed kernel [] = { |
645 | XFixed kernel [] = { |
645 | XDoubleToFixed (3), XDoubleToFixed (1), |
646 | XDoubleToFixed (3), XDoubleToFixed (1), |
646 | XDoubleToFixed (0), XDoubleToFixed (mul), XDoubleToFixed (add) |
647 | XDoubleToFixed (0), XDoubleToFixed (mul), XDoubleToFixed (add) |
647 | }; |
648 | }; |
… | |
… | |
656 | XRenderSetPictureTransform (cc.dpy, cc2.src, &h_halve); |
657 | XRenderSetPictureTransform (cc.dpy, cc2.src, &h_halve); |
657 | XRenderSetPictureFilter (cc.dpy, cc2.src, FilterConvolution, kernel, ecb_array_length (kernel)); |
658 | XRenderSetPictureFilter (cc.dpy, cc2.src, FilterConvolution, kernel, ecb_array_length (kernel)); |
658 | |
659 | |
659 | XRenderComposite (cc.dpy, PictOpSrc, cc2.src, None, cc2.dst, 0, 0, 0, 0, 0, 0, w * 2, h); |
660 | XRenderComposite (cc.dpy, PictOpSrc, cc2.src, None, cc2.dst, 0, 0, 0, 0, 0, 0, w * 2, h); |
660 | |
661 | |
|
|
662 | delete img; |
|
|
663 | |
661 | return cc2; |
664 | return cc2; |
662 | } |
665 | } |
663 | |
666 | |
664 | ecb_noinline static void |
667 | ecb_noinline static void |
665 | extract (int32_t cl0, int32_t cl1, int32_t &c, unsigned short &xc) |
668 | extract (int32_t cl0, int32_t cl1, int32_t &c, unsigned short &xc) |
… | |
… | |
689 | Picture dst = XRenderCreatePicture (dpy, pm, format, 0, 0); |
692 | Picture dst = XRenderCreatePicture (dpy, pm, format, 0, 0); |
690 | |
693 | |
691 | // loop should not be needed for brightness, as only -1..1 makes sense |
694 | // loop should not be needed for brightness, as only -1..1 makes sense |
692 | //while (r | g | b | a) |
695 | //while (r | g | b | a) |
693 | { |
696 | { |
694 | unsigned short xr, xg, xb, xa; |
|
|
695 | XRenderColor mask_c; |
697 | XRenderColor mask_c; |
696 | |
698 | |
697 | if (extract (0, 65535, r, g, b, a, mask_c.red, mask_c.green, mask_c.blue, mask_c.alpha)) |
699 | if (extract (0, 65535, r, g, b, a, mask_c.red, mask_c.green, mask_c.blue, mask_c.alpha)) |
698 | XRenderFillRectangle (dpy, PictOpAdd, dst, &mask_c, 0, 0, w, h); |
700 | XRenderFillRectangle (dpy, PictOpAdd, dst, &mask_c, 0, 0, w, h); |
699 | |
701 | |
… | |
… | |
731 | cc.mask (true); |
733 | cc.mask (true); |
732 | |
734 | |
733 | //TODO: this operator does not yet implement some useful contrast |
735 | //TODO: this operator does not yet implement some useful contrast |
734 | while (r | g | b | a) |
736 | while (r | g | b | a) |
735 | { |
737 | { |
736 | unsigned short xr, xg, xb, xa; |
|
|
737 | XRenderColor mask_c; |
738 | XRenderColor mask_c; |
738 | |
739 | |
739 | if (extract (0, 65535, r, g, b, a, mask_c.red, mask_c.green, mask_c.blue, mask_c.alpha)) |
740 | if (extract (0, 65535, r, g, b, a, mask_c.red, mask_c.green, mask_c.blue, mask_c.alpha)) |
740 | { |
741 | { |
741 | XRenderFillRectangle (cc.dpy, PictOpSrc, cc.msk, &mask_c, 0, 0, 1, 1); |
742 | XRenderFillRectangle (cc.dpy, PictOpSrc, cc.msk, &mask_c, 0, 0, 1, 1); |