ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/rxvt-unicode/src/rxvtimg.C
Revision: 1.9
Committed: Sun Jun 3 20:47:00 2012 UTC (11 years, 11 months ago) by root
Content type: text/plain
Branch: MAIN
Changes since 1.8: +2 -1 lines
Log Message:
*** empty log message ***

File Contents

# Content
1 #include <math.h>
2 #include "../config.h"
3 #include "rxvt.h"
4
5 #if HAVE_IMG
6
7 #define float_to_component(d) ((d) * 65535.99)
8
9 rxvt_img::rxvt_img (rxvt_screen *screen, XRenderPictFormat *format, int width, int height)
10 : s(screen), w(width), h(height), format(format), shared(false)
11 {
12 pm = XCreatePixmap (s->display->dpy, s->display->root, w, h, format->depth);
13 }
14
15 rxvt_img::rxvt_img (rxvt_screen *screen, XRenderPictFormat *format, int width, int height, Pixmap pixmap)
16 : s(screen), pm(pixmap), w(width), h(height), format(format), shared(false)
17 {
18 }
19
20 rxvt_img *
21 rxvt_img::new_from_file (rxvt_screen *s, const char *filename)
22 {
23 GError *err;
24 GdkPixbuf *pb = gdk_pixbuf_new_from_file (filename, &err);
25
26 if (!pb)
27 return 0;
28
29 rxvt_img *img = new rxvt_img (
30 s,
31 XRenderFindStandardFormat (s->display->dpy, gdk_pixbuf_get_has_alpha (pb) ? PictStandardARGB32 : PictStandardRGB24),
32 gdk_pixbuf_get_width (pb),
33 gdk_pixbuf_get_height (pb)
34 );
35
36 img->render (pb, 0, 0, img->w, img->h, 0, 0);
37
38 return img;
39 }
40
41 rxvt_img::~rxvt_img ()
42 {
43 if (!shared)
44 XFreePixmap (s->display->dpy, pm);
45 }
46
47 void
48 rxvt_img::fill (const rxvt_color &c)
49 {
50 XGCValues gcv;
51 gcv.foreground = c;
52 GC gc = XCreateGC (s->display->dpy, pm, GCForeground, &gcv);
53 XFillRectangle (s->display->dpy, pm, gc, 0, 0, w, h);
54 XFreeGC (s->display->dpy, gc);
55 }
56
57 static void
58 get_gaussian_kernel (int radius, int width, double *kernel, XFixed *params)
59 {
60 double sigma = radius / 2.0;
61 double scale = sqrt (2.0 * M_PI) * sigma;
62 double sum = 0.0;
63
64 for (int i = 0; i < width; i++)
65 {
66 double x = i - width / 2;
67 kernel[i] = exp (-(x * x) / (2.0 * sigma * sigma)) / scale;
68 sum += kernel[i];
69 }
70
71 params[0] = XDoubleToFixed (width);
72 params[1] = XDoubleToFixed (1);
73
74 for (int i = 0; i < width; i++)
75 params[i+2] = XDoubleToFixed (kernel[i] / sum);
76 }
77
78 void
79 rxvt_img::blur (int rh, int rv)
80 {
81 if (!(s->display->flags & DISPLAY_HAS_RENDER_CONV))
82 return;
83
84 Display *dpy = s->display->dpy;
85 int size = max (rh, rv) * 2 + 1;
86 double *kernel = (double *)malloc (size * sizeof (double));
87 XFixed *params = (XFixed *)malloc ((size + 2) * sizeof (XFixed));
88
89 XRenderPictureAttributes pa;
90
91 pa.repeat = RepeatPad;
92 Picture src = XRenderCreatePicture (dpy, pm, format, CPRepeat, &pa);
93 Pixmap tmp = XCreatePixmap (dpy, pm, w, h, format->depth);
94 Picture dst = XRenderCreatePicture (dpy, tmp, format, CPRepeat, &pa);
95 XFreePixmap (dpy, tmp);
96
97 if (kernel && params)
98 {
99 size = rh * 2 + 1;
100 get_gaussian_kernel (rh, size, kernel, params);
101
102 XRenderSetPictureFilter (dpy, src, FilterConvolution, params, size+2);
103 XRenderComposite (dpy,
104 PictOpSrc,
105 src,
106 None,
107 dst,
108 0, 0,
109 0, 0,
110 0, 0,
111 w, h);
112
113 ::swap (src, dst);
114
115 size = rv * 2 + 1;
116 get_gaussian_kernel (rv, size, kernel, params);
117 ::swap (params[0], params[1]);
118
119 XRenderSetPictureFilter (dpy, src, FilterConvolution, params, size+2);
120 XRenderComposite (dpy,
121 PictOpSrc,
122 src,
123 None,
124 dst,
125 0, 0,
126 0, 0,
127 0, 0,
128 w, h);
129 }
130
131 free (kernel);
132 free (params);
133 XRenderFreePicture (dpy, src);
134 XRenderFreePicture (dpy, dst);
135 }
136
137 static Picture
138 create_xrender_mask (Display *dpy, Drawable drawable, Bool argb)
139 {
140 Pixmap pixmap = XCreatePixmap (dpy, drawable, 1, 1, argb ? 32 : 8);
141
142 XRenderPictFormat *format = XRenderFindStandardFormat (dpy, argb ? PictStandardARGB32 : PictStandardA8);
143 XRenderPictureAttributes pa;
144 pa.repeat = True;
145 Picture mask = XRenderCreatePicture (dpy, pixmap, format, CPRepeat, &pa);
146
147 XFreePixmap (dpy, pixmap);
148
149 return mask;
150 }
151
152 void
153 rxvt_img::brightness (double r, double g, double b, double a)
154 {
155 Display *dpy = s->display->dpy;
156 Picture src = create_xrender_mask (dpy, pm, True);
157 Picture dst = XRenderCreatePicture (dpy, pm, format, 0, 0);
158
159 XRenderColor mask_c;
160 mask_c.red = float_to_component (r);
161 mask_c.green = float_to_component (g);
162 mask_c.blue = float_to_component (b);
163 mask_c.alpha = float_to_component (a);
164 XRenderFillRectangle (dpy, PictOpSrc, src, &mask_c, 0, 0, 1, 1);
165
166 XRenderComposite (dpy, PictOpAdd, src, None, dst, 0, 0, 0, 0, 0, 0, w, h);
167 }
168
169 void
170 rxvt_img::contrast (double r, double g, double b, double a)
171 {
172 if (!(s->display->flags & DISPLAY_HAS_RENDER_MUL))
173 return;
174
175 Display *dpy = s->display->dpy;
176 Picture src = create_xrender_mask (dpy, pm, True);
177 Picture dst = XRenderCreatePicture (dpy, pm, format, 0, 0);
178
179 XRenderColor mask_c;
180 mask_c.red = float_to_component (r);
181 mask_c.green = float_to_component (g);
182 mask_c.blue = float_to_component (b);
183 mask_c.alpha = float_to_component (a);
184 XRenderFillRectangle (dpy, PictOpSrc, src, &mask_c, 0, 0, 1, 1);
185
186 XRenderComposite (dpy, PictOpMultiply, src, None, dst, 0, 0, 0, 0, 0, 0, w, h);
187 }
188
189 void
190 rxvt_img::render (GdkPixbuf *pixbuf, int src_x, int src_y, int width, int height, int dst_x, int dst_y)
191 {
192 //TODO
193 }
194
195 rxvt_img *
196 rxvt_img::copy ()
197 {
198 GC gc = XCreateGC (s->display->dpy, pm, 0, 0);
199 Pixmap pm2 = XCreatePixmap (s->display->dpy, pm, w, h, format->depth);
200 XCopyArea (s->display->dpy, pm, pm2, gc, 0, 0, w, h, 0, 0);
201 XFreeGC (s->display->dpy, gc);
202 return new rxvt_img (s, format, w, h, pm2);
203 }
204
205 rxvt_img *
206 rxvt_img::transform (int new_width, int new_height, double matrix[16])
207 {
208 //TODO
209 }
210
211 rxvt_img *
212 rxvt_img::scale (int new_width, int new_height)
213 {
214 // use transform
215 //TODO
216 }
217
218 rxvt_img *
219 rxvt_img::convert_to (XRenderPictFormat *new_format)
220 {
221 rxvt_img *img = new rxvt_img (s,new_format,w, h);
222
223 Display *dpy = s->display->dpy;
224 Picture src = XRenderCreatePicture (dpy, pm, format, 0, 0);
225 Picture dst = XRenderCreatePicture (dpy, img->pm, new_format, 0, 0);
226
227 XRenderComposite (dpy, PictOpSrc, src, None, dst, 0, 0, 0, 0, 0, 0, w, h);
228
229 XRenderFreePicture (dpy, src);
230 XRenderFreePicture (dpy, dst);
231
232 return img;
233 }
234
235 #endif
236