ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/rxvt-unicode/src/rxvtimg.C
(Generate patch)

Comparing rxvt-unicode/src/rxvtimg.C (file contents):
Revision 1.92 by root, Fri Jun 15 18:05:15 2012 UTC vs.
Revision 1.97 by sf-exg, Sun Jun 17 17:06:47 2012 UTC

1/*----------------------------------------------------------------------*
2 * File: rxvtimg.C
3 *----------------------------------------------------------------------*
4 *
5 * All portions of code are copyright by their respective author/s.
6 * Copyright (c) 2012 Marc Lehmann <schmorp@schmorp.de>
7 * Copyright (c) 2012 Emanuele Giaquinta <e.giaquinta@glauco.it>
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 *---------------------------------------------------------------------*/
23
1#include <string.h> 24#include <string.h>
2#include <math.h> 25#include <math.h>
3#include "../config.h" 26#include "../config.h"
4#include "rxvt.h" 27#include "rxvt.h"
5 28
6#if HAVE_IMG 29#if HAVE_IMG
7 30
8typedef rxvt_img::nv nv; 31typedef rxvt_img::nv nv;
9 32
33namespace
34{
35
10struct mat3x3 36 struct mat3x3
11{
12 nv v[3][3];
13
14 mat3x3 ()
15 { 37 {
16 } 38 nv v[3][3];
17 39
18 mat3x3 (nv matrix[3][3]) 40 mat3x3 ()
19 { 41 {
42 }
43
44 mat3x3 (const nv *matrix)
45 {
20 memcpy (v, matrix, sizeof (v)); 46 memcpy (v, matrix, sizeof (v));
21 } 47 }
22 48
23 mat3x3 (nv v11, nv v12, nv v13, nv v21, nv v22, nv v23, nv v31, nv v32, nv v33) 49 mat3x3 (nv v11, nv v12, nv v13, nv v21, nv v22, nv v23, nv v31, nv v32, nv v33)
24 { 50 {
25 v[0][0] = v11; v[0][1] = v12; v[0][2] = v13; 51 v[0][0] = v11; v[0][1] = v12; v[0][2] = v13;
26 v[1][0] = v21; v[1][1] = v22; v[1][2] = v23; 52 v[1][0] = v21; v[1][1] = v22; v[1][2] = v23;
27 v[2][0] = v31; v[2][1] = v32; v[2][2] = v33; 53 v[2][0] = v31; v[2][1] = v32; v[2][2] = v33;
28 } 54 }
29 55
30 mat3x3 invert (); 56 mat3x3 invert ();
31 57
32 nv *operator [](int i) { return &v[i][0]; } 58 nv *operator [](int i) { return &v[i][0]; }
33 const nv *operator [](int i) const { return &v[i][0]; } 59 const nv *operator [](int i) const { return &v[i][0]; }
34 60
61 operator const nv * () const { return &v[0][0]; }
62 operator nv * () { return &v[0][0]; }
63
35 // quite inefficient, hopefully gcc pulls the w calc out of any loops 64 // quite inefficient, hopefully gcc pulls the w calc out of any loops
36 nv apply1 (int i, nv x, nv y) 65 nv apply1 (int i, nv x, nv y)
66 {
67 mat3x3 &m = *this;
68
69 nv v = m[i][0] * x + m[i][1] * y + m[i][2];
70 nv w = m[2][0] * x + m[2][1] * y + m[2][2];
71
72 return v * (1. / w);
73 }
74
75 static mat3x3 translate (nv x, nv y);
76 static mat3x3 scale (nv s, nv t);
77 static mat3x3 rotate (nv phi);
78 };
79
80 mat3x3
81 mat3x3::invert ()
37 { 82 {
38 mat3x3 &m = *this; 83 mat3x3 &m = *this;
84 mat3x3 inv;
39 85
40 nv v = m[i][0] * x + m[i][1] * y + m[i][2];
41 nv w = m[2][0] * x + m[2][1] * y + m[2][2]; 86 nv s0 = m[2][2] * m[1][1] - m[2][1] * m[1][2];
87 nv s1 = m[2][1] * m[0][2] - m[2][2] * m[0][1];
88 nv s2 = m[1][2] * m[0][1] - m[1][1] * m[0][2];
42 89
43 return v * (1. / w); 90 nv invdet = 1. / (m[0][0] * s0 + m[1][0] * s1 + m[2][0] * s2);
91
92 inv[0][0] = invdet * s0;
93 inv[0][1] = invdet * s1;
94 inv[0][2] = invdet * s2;
95
96 inv[1][0] = invdet * (m[2][0] * m[1][2] - m[2][2] * m[1][0]);
97 inv[1][1] = invdet * (m[2][2] * m[0][0] - m[2][0] * m[0][2]);
98 inv[1][2] = invdet * (m[1][0] * m[0][2] - m[1][2] * m[0][0]);
99
100 inv[2][0] = invdet * (m[2][1] * m[1][0] - m[2][0] * m[1][1]);
101 inv[2][1] = invdet * (m[2][0] * m[0][1] - m[2][1] * m[0][0]);
102 inv[2][2] = invdet * (m[1][1] * m[0][0] - m[1][0] * m[0][1]);
103
104 return inv;
44 } 105 }
45 106
46 static mat3x3 translate (nv x, nv y);
47};
48
49mat3x3
50mat3x3::invert ()
51{
52 mat3x3 &m = *this;
53 mat3x3 inv;
54
55 nv s0 = m[2][2] * m[1][1] - m[2][1] * m[1][2];
56 nv s1 = m[2][1] * m[0][2] - m[2][2] * m[0][1];
57 nv s2 = m[1][2] * m[0][1] - m[1][1] * m[0][2];
58
59 nv invdet = 1. / (m[0][0] * s0 + m[1][0] * s1 + m[2][0] * s2);
60
61 inv[0][0] = invdet * s0;
62 inv[0][1] = invdet * s1;
63 inv[0][2] = invdet * s2;
64
65 inv[1][0] = invdet * (m[2][0] * m[1][2] - m[2][2] * m[1][0]);
66 inv[1][1] = invdet * (m[2][2] * m[0][0] - m[2][0] * m[0][2]);
67 inv[1][2] = invdet * (m[1][0] * m[0][2] - m[1][2] * m[0][0]);
68
69 inv[2][0] = invdet * (m[2][1] * m[1][0] - m[2][0] * m[1][1]);
70 inv[2][1] = invdet * (m[2][0] * m[0][1] - m[2][1] * m[0][0]);
71 inv[2][2] = invdet * (m[1][1] * m[0][0] - m[1][0] * m[0][1]);
72
73 return inv;
74}
75
76static mat3x3 107 static mat3x3
77operator *(const mat3x3 &a, const mat3x3 &b) 108 operator *(const mat3x3 &a, const mat3x3 &b)
78{ 109 {
79 mat3x3 r; 110 mat3x3 r;
80 111
81 for (int i = 0; i < 3; ++i) 112 for (int i = 0; i < 3; ++i)
82 for (int j = 0; j < 3; ++j) 113 for (int j = 0; j < 3; ++j)
83 r[i][j] = a[i][0] * b[0][j] 114 r[i][j] = a[i][0] * b[0][j]
84 + a[i][1] * b[1][j] 115 + a[i][1] * b[1][j]
85 + a[i][2] * b[2][j]; 116 + a[i][2] * b[2][j];
86 117
87 return r; 118 return r;
88} 119 }
89 120
90mat3x3 121 mat3x3
91mat3x3::translate (nv x, nv y) 122 mat3x3::translate (nv x, nv y)
92{ 123 {
93 return mat3x3 ( 124 return mat3x3 (
94 1, 0, x, 125 1, 0, x,
95 0, 1, y, 126 0, 1, y,
96 0, 0, 1 127 0, 0, 1
97 ); 128 );
129 }
130
131 mat3x3
132 mat3x3::scale (nv s, nv t)
133 {
134 return mat3x3 (
135 s, 0, 0,
136 0, t, 0,
137 0, 0, 1
138 );
139 }
140
141 // clockwise
142 mat3x3
143 mat3x3::rotate (nv phi)
144 {
145 nv s = sin (phi);
146 nv c = cos (phi);
147
148 return mat3x3 (
149 c, -s, 0,
150 s, c, 0,
151 0, 0, 1
152 );
153 }
154
98} 155}
99 156
100#if 0 157#if 0
101struct pict 158struct pict
102{ 159{
259 uint8_t r = *src++; 316 uint8_t r = *src++;
260 uint8_t g = *src++; 317 uint8_t g = *src++;
261 uint8_t b = *src++; 318 uint8_t b = *src++;
262 319
263 uint32_t v = (255 << 24) | (r << 16) | (g << 8) | b; 320 uint32_t v = (255 << 24) | (r << 16) | (g << 8) | b;
264 321
265 if (ecb_big_endian () ? !byte_order_mismatch : byte_order_mismatch) 322 if (ecb_big_endian () ? !byte_order_mismatch : byte_order_mismatch)
266 v = ecb_bswap32 (v); 323 v = ecb_bswap32 (v);
267 324
268 *dst++ = v; 325 *dst++ = v;
269 } 326 }
392 rxvt_img *img = new rxvt_img (s, find_alpha_format_for (dpy, format), x, y, w, h, repeat); 449 rxvt_img *img = new rxvt_img (s, find_alpha_format_for (dpy, format), x, y, w, h, repeat);
393 img->alloc (); 450 img->alloc ();
394 451
395 Picture src = picture (); 452 Picture src = picture ();
396 Picture dst = XRenderCreatePicture (dpy, img->pm, img->format, 0, 0); 453 Picture dst = XRenderCreatePicture (dpy, img->pm, img->format, 0, 0);
397 454
398 XRenderComposite (dpy, PictOpSrc, src, None, dst, 0, 0, 0, 0, 0, 0, w, h); 455 XRenderComposite (dpy, PictOpSrc, src, None, dst, 0, 0, 0, 0, 0, 0, w, h);
399 456
400 XRenderFreePicture (dpy, src); 457 XRenderFreePicture (dpy, src);
401 XRenderFreePicture (dpy, dst); 458 XRenderFreePicture (dpy, dst);
402 459
610 667
611 Display *dpy = s->display->dpy; 668 Display *dpy = s->display->dpy;
612 Picture src = img->picture (); 669 Picture src = img->picture ();
613 Picture dst = picture (); 670 Picture dst = picture ();
614 Picture mask_p = 0; 671 Picture mask_p = 0;
615 672
616 if (mask != 1.) 673 if (mask != 1.)
617 { 674 {
618 mask_p = create_xrender_mask (dpy, img->pm, False, False); 675 mask_p = create_xrender_mask (dpy, img->pm, False, False);
619 XRenderColor mask_c = { 0, 0, 0, float_to_component (mask) }; 676 XRenderColor mask_c = { 0, 0, 0, float_to_component (mask) };
620 XRenderFillRectangle (dpy, PictOpSrc, mask, &mask_c, 0, 0, 1, 1); 677 XRenderFillRectangle (dpy, PictOpSrc, mask, &mask_c, 0, 0, 1, 1);
651 rxvt_img *img = new rxvt_img (s, alpha ? find_alpha_format_for (dpy, format) : format, 0, 0, w, h, repeat); 708 rxvt_img *img = new rxvt_img (s, alpha ? find_alpha_format_for (dpy, format) : format, 0, 0, w, h, repeat);
652 img->alloc (); 709 img->alloc ();
653 710
654 Picture src = picture (); 711 Picture src = picture ();
655 Picture dst = XRenderCreatePicture (dpy, img->pm, img->format, 0, 0); 712 Picture dst = XRenderCreatePicture (dpy, img->pm, img->format, 0, 0);
656 713
657 if (alpha) 714 if (alpha)
658 { 715 {
659 XRenderColor rc = { 0, 0, 0, 0 }; 716 XRenderColor rc = { 0, 0, 0, 0 };
660 XRenderFillRectangle (dpy, PictOpSrc, dst, &rc, 0, 0, w, h);//TODO: split into four fillrectangles 717 XRenderFillRectangle (dpy, PictOpSrc, dst, &rc, 0, 0, w, h);//TODO: split into four fillrectangles
661 XRenderComposite (dpy, PictOpSrc, src, None, dst, 0, 0, 0, 0, x, y, ref->w, ref->h); 718 XRenderComposite (dpy, PictOpSrc, src, None, dst, 0, 0, 0, 0, x, y, ref->w, ref->h);
689 746
690 return img; 747 return img;
691} 748}
692 749
693rxvt_img * 750rxvt_img *
694rxvt_img::transform (nv matrix[3][3]) 751rxvt_img::transform (const nv matrix[3][3])
695{ 752{
753 return transform (mat3x3 (&matrix[0][0]));
754}
755
756rxvt_img *
757rxvt_img::transform (const nv *matrix)
758{
759 mat3x3 m (matrix);
760
696 // calculate new pixel bounding box coordinates 761 // calculate new pixel bounding box coordinates
697 nv r[2], rmin[2], rmax[2]; 762 nv r[2], rmin[2], rmax[2];
698
699 mat3x3 m (matrix);
700 763
701 for (int i = 0; i < 2; ++i) 764 for (int i = 0; i < 2; ++i)
702 { 765 {
703 nv v; 766 nv v;
704 767
736 xfrm.matrix [i][j] = XDoubleToFixed (inv [i][j]); 799 xfrm.matrix [i][j] = XDoubleToFixed (inv [i][j]);
737 800
738 XRenderSetPictureFilter (dpy, src, "good", 0, 0); 801 XRenderSetPictureFilter (dpy, src, "good", 0, 0);
739 XRenderSetPictureTransform (dpy, src, &xfrm); 802 XRenderSetPictureTransform (dpy, src, &xfrm);
740 XRenderComposite (dpy, PictOpSrc, src, None, dst, sx, sy, 0, 0, 0, 0, new_width, new_height); 803 XRenderComposite (dpy, PictOpSrc, src, None, dst, sx, sy, 0, 0, 0, 0, new_width, new_height);
741#if 1
742 {
743 XRenderColor rc = { 65535,0,0,65535 };
744 XRenderFillRectangle (dpy, PictOpSrc, dst, &rc, 0, 0, new_width, new_height);
745 }{
746 XRenderColor rc = { 0,0,0,65535 };
747 XRenderFillRectangle (dpy, PictOpSrc, dst, &rc, 1, 1, new_width - 2, new_height - 2);
748 }
749 XRenderComposite (dpy, PictOpOver, src, None, dst, sx, sy, 0, 0, 0, 0, new_width, new_height);
750#endif
751 804
752 XRenderFreePicture (dpy, src); 805 XRenderFreePicture (dpy, src);
753 XRenderFreePicture (dpy, dst); 806 XRenderFreePicture (dpy, dst);
754 807
755 return img; 808 return img;
759rxvt_img::scale (int new_width, int new_height) 812rxvt_img::scale (int new_width, int new_height)
760{ 813{
761 if (w == new_width && h == new_height) 814 if (w == new_width && h == new_height)
762 return clone (); 815 return clone ();
763 816
764 nv matrix[3][3] = {
765 { new_width / (nv)w, 0, 0 },
766 { 0, new_height / (nv)h, 0 },
767 { 0, 0, 1 }
768 };
769
770 int old_repeat_mode = repeat; 817 int old_repeat_mode = repeat;
771 repeat = RepeatPad; // not right, but xrender can't properly scale it seems 818 repeat = RepeatPad; // not right, but xrender can't properly scale it seems
772 819
773 rxvt_img *img = transform (matrix); 820 rxvt_img *img = transform (mat3x3::scale (new_width / (nv)w, new_height / (nv)h));
774 821
775 repeat = old_repeat_mode; 822 repeat = old_repeat_mode;
776 img->repeat = repeat; 823 img->repeat = repeat;
777 824
778 return img; 825 return img;
779} 826}
780 827
781rxvt_img * 828rxvt_img *
782rxvt_img::rotate (int cx, int cy, nv phi) 829rxvt_img::rotate (int cx, int cy, nv phi)
783{ 830{
784 nv s = sin (phi);
785 nv c = cos (phi);
786
787 nv matrix[3][3] = {
788#if 0 831#if 0
789 { c, -s, cx - c * cx + s * cy }, 832 { c, -s, cx - c * cx + s * cy },
790 { s, c, cy - s * cx - c * cy }, 833 { s, c, cy - s * cx - c * cy },
791 { 0, 0, 1 } 834 { 0, 0, 1 }
792#else
793 { c, -s, 0 },
794 { s, c, 0 },
795 { 0, 0, 1 }
796#endif 835#endif
797 };
798 836
799 move (-cx, -cy); 837 move (-cx, -cy);
800 rxvt_img *img = transform (matrix); 838 rxvt_img *img = transform (mat3x3::rotate (phi));
801 move ( cx, cy); 839 move ( cx, cy);
802 img->move (cx, cy); 840 img->move (cx, cy);
803 841
804 return img; 842 return img;
805} 843}

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines