… | |
… | |
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 | }; |
… | |
… | |
655 | XRenderSetPictureFilter (cc.dpy, cc2.src, "nearest", 0, 0); |
656 | XRenderSetPictureFilter (cc.dpy, cc2.src, "nearest", 0, 0); |
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); |
|
|
661 | |
|
|
662 | delete img; |
660 | |
663 | |
661 | return cc2; |
664 | return cc2; |
662 | } |
665 | } |
663 | |
666 | |
664 | ecb_noinline static void |
667 | ecb_noinline static void |