ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/rxvt-unicode/src/rxvtimg.C
Revision: 1.12
Committed: Mon Jun 4 15:28:49 2012 UTC (11 years, 11 months ago) by root
Content type: text/plain
Branch: MAIN
Changes since 1.11: +20 -2 lines
Log Message:
*** empty log message ***

File Contents

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