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.96 by root, Sat Jun 16 15:55:19 2012 UTC

1/*----------------------------------------------------------------------*
2 * File: rxvtimg.h
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{
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