ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/rxvt-unicode/src/rxvtimg.C
Revision: 1.7
Committed: Sun Jun 3 20:34:25 2012 UTC (11 years, 11 months ago) by sf-exg
Content type: text/plain
Branch: MAIN
Changes since 1.6: +23 -0 lines
Log Message:
Add method to convert an rxvt_img to another format.

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     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 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     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 root 1.3 XFreeGC (s->display->dpy, gc);
55 root 1.1 }
56    
57 sf-exg 1.6 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 root 1.3 void
79     rxvt_img::blur (int rh, int rv)
80     {
81 sf-exg 1.6 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 root 1.3 }
151    
152     void
153     rxvt_img::brightness (double r, double g, double b, double a)
154     {
155 sf-exg 1.6 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 root 1.3 }
168    
169     void
170     rxvt_img::contrast (double r, double g, double b, double a)
171 root 1.1 {
172 sf-exg 1.6 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 root 1.1 }
188    
189 root 1.3 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 sf-exg 1.7 rxvt_img *
219     rxvt_img::convert_to (XRenderPictFormat *new_format)
220     {
221     Display *dpy = s->display->dpy;
222     Pixmap new_pm = XCreatePixmap (dpy, pm, w, h, new_format->depth);
223     Picture src = XRenderCreatePicture (dpy, pm, format, 0, 0);
224     Picture dst = XRenderCreatePicture (dpy, new_pm, new_format, 0, 0);
225    
226     XRenderComposite (dpy, PictOpSrc, src, None, dst, 0, 0, 0, 0, 0, 0, w, h);
227    
228     XRenderFreePicture (dpy, src);
229     XRenderFreePicture (dpy, dst);
230    
231     rxvt_img *img = new rxvt_img (
232     s,
233     new_format,
234     w,
235     h,
236     new_pm
237     );
238    
239     return img;
240     }
241 root 1.3
242 root 1.1 #endif
243