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.13 by root, Mon Jun 4 15:30:41 2012 UTC vs.
Revision 1.33 by root, Thu Jun 7 08:12:55 2012 UTC

2#include "../config.h" 2#include "../config.h"
3#include "rxvt.h" 3#include "rxvt.h"
4 4
5#if HAVE_IMG 5#if HAVE_IMG
6 6
7#define float_to_component(d) ((d) * 65535.99)
8
9rxvt_img::rxvt_img (rxvt_screen *screen, XRenderPictFormat *format, int width, int height) 7rxvt_img::rxvt_img (rxvt_screen *screen, XRenderPictFormat *format, int x, int y, int width, int height)
10: s(screen), w(width), h(height), format(format), shared(false) 8: s(screen), x(x), y(y), w(width), h(height), format(format), repeat(RepeatNormal),
9 pm(0), refcnt(0)
11{ 10{
12 pm = XCreatePixmap (s->display->dpy, s->display->root, w, h, format->depth);
13} 11}
14 12
13rxvt_img::rxvt_img (const rxvt_img &img)
14: s(img.s), x(img.x), y(img.y), w(img.w), h(img.h), format(img.format), repeat(img.repeat), pm(img.pm), refcnt(img.refcnt)
15{
16 if (refcnt)
17 ++*refcnt;
18}
19
20#if 0
15rxvt_img::rxvt_img (rxvt_screen *screen, XRenderPictFormat *format, int width, int height, Pixmap pixmap) 21rxvt_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) 22: s(screen), x(0), y(0), w(width), h(height), format(format), repeat(RepeatNormal), shared(false), pm(pixmap)
17{ 23{
24}
25#endif
26
27rxvt_img *
28rxvt_img::new_from_root (rxvt_screen *s)
29{
30 Display *dpy = s->display->dpy;
31 unsigned int root_pm_w, root_pm_h;
32 Pixmap root_pixmap = s->display->get_pixmap_property (s->display->xa[XA_XROOTPMAP_ID]);
33 if (root_pixmap == None)
34 root_pixmap = s->display->get_pixmap_property (s->display->xa[XA_ESETROOT_PMAP_ID]);
35
36 if (root_pixmap == None)
37 return 0;
38
39 Window wdummy;
40 int idummy;
41 unsigned int udummy;
42
43 if (!XGetGeometry (dpy, root_pixmap, &wdummy, &idummy, &idummy, &root_pm_w, &root_pm_h, &udummy, &udummy))
44 return 0;
45
46 rxvt_img *img = new rxvt_img (
47 s,
48 XRenderFindVisualFormat (dpy, DefaultVisual (dpy, s->display->screen)),
49 0,
50 0,
51 root_pm_w,
52 root_pm_h
53 );
54
55 img->pm = root_pixmap;
56
57 return img;
18} 58}
19 59
20rxvt_img * 60rxvt_img *
21rxvt_img::new_from_file (rxvt_screen *s, const char *filename) 61rxvt_img::new_from_file (rxvt_screen *s, const char *filename)
22{ 62{
27 rxvt_fatal ("rxvt_img::new_from_file: %s\n", err->message); 67 rxvt_fatal ("rxvt_img::new_from_file: %s\n", err->message);
28 68
29 rxvt_img *img = new rxvt_img ( 69 rxvt_img *img = new rxvt_img (
30 s, 70 s,
31 XRenderFindStandardFormat (s->display->dpy, gdk_pixbuf_get_has_alpha (pb) ? PictStandardARGB32 : PictStandardRGB24), 71 XRenderFindStandardFormat (s->display->dpy, gdk_pixbuf_get_has_alpha (pb) ? PictStandardARGB32 : PictStandardRGB24),
72 0,
73 0,
32 gdk_pixbuf_get_width (pb), 74 gdk_pixbuf_get_width (pb),
33 gdk_pixbuf_get_height (pb) 75 gdk_pixbuf_get_height (pb)
34 ); 76 );
35 77 img->alloc ();
36 img->render (pb, 0, 0, img->w, img->h, 0, 0); 78 img->render_pixbuf (pb, 0, 0, img->w, img->h, 0, 0);
37 79
80 g_object_unref (pb);
81
82 return img;
83}
84
85void
86rxvt_img::destroy ()
87{
88 if (!refcnt || --*refcnt)
38 return img; 89 return;
90
91 if (pm)
92 XFreePixmap (s->display->dpy, pm);
93
94 delete refcnt;
39} 95}
40 96
41rxvt_img::~rxvt_img () 97rxvt_img::~rxvt_img ()
42{ 98{
43 if (!shared) 99 destroy ();
44 XFreePixmap (s->display->dpy, pm); 100}
101
102void
103rxvt_img::alloc ()
104{
105 pm = XCreatePixmap (s->display->dpy, s->display->root, w, h, format->depth);
106 refcnt = new int (1);
45} 107}
46 108
47void 109void
48rxvt_img::unshare () 110rxvt_img::unshare ()
49{ 111{
50 if (!shared) 112 if (refcnt && *refcnt == 1)
51 return; 113 return;
52 114
53 rxvt_img *img = clone (); 115 Pixmap pm2 = XCreatePixmap (s->display->dpy, s->display->root, w, h, format->depth);
116 GC gc = XCreateGC (s->display->dpy, pm, 0, 0);
117 XCopyArea (s->display->dpy, pm, pm2, gc, 0, 0, w, h, 0, 0);
118 XFreeGC (s->display->dpy, gc);
54 119
55 ::swap (pm , img->pm); 120 destroy ();
56 ::swap (shared, img->shared);
57 121
58 delete img; 122 pm = pm2;
123 refcnt = new int (1);
59} 124}
60 125
61void 126void
62rxvt_img::fill (const rxvt_color &c) 127rxvt_img::fill (const rxvt_color &c)
63{ 128{
87 152
88 for (int i = 0; i < width; i++) 153 for (int i = 0; i < width; i++)
89 params[i+2] = XDoubleToFixed (kernel[i] / sum); 154 params[i+2] = XDoubleToFixed (kernel[i] / sum);
90} 155}
91 156
92void 157rxvt_img *
93rxvt_img::blur (int rh, int rv) 158rxvt_img::blur (int rh, int rv)
94{ 159{
95 if (!(s->display->flags & DISPLAY_HAS_RENDER_CONV)) 160 if (!(s->display->flags & DISPLAY_HAS_RENDER_CONV))
96 return; 161 return clone ();
97 162
98 Display *dpy = s->display->dpy; 163 Display *dpy = s->display->dpy;
99 int size = max (rh, rv) * 2 + 1; 164 int size = max (rh, rv) * 2 + 1;
100 double *kernel = (double *)malloc (size * sizeof (double)); 165 double *kernel = (double *)malloc (size * sizeof (double));
101 XFixed *params = (XFixed *)malloc ((size + 2) * sizeof (XFixed)); 166 XFixed *params = (XFixed *)malloc ((size + 2) * sizeof (XFixed));
167 rxvt_img *img = new rxvt_img (s, format, x, y, w, h);
168 img->alloc ();
102 169
103 XRenderPictureAttributes pa; 170 XRenderPictureAttributes pa;
104 171
105 pa.repeat = RepeatPad; 172 pa.repeat = RepeatPad;
106 Picture src = XRenderCreatePicture (dpy, pm, format, CPRepeat, &pa); 173 Picture src = XRenderCreatePicture (dpy, pm , format, CPRepeat, &pa);
174 Picture dst = XRenderCreatePicture (dpy, img->pm, format, CPRepeat, &pa);
175
107 Pixmap tmp = XCreatePixmap (dpy, pm, w, h, format->depth); 176 Pixmap tmp_pm = XCreatePixmap (dpy, pm, w, h, format->depth);
108 Picture dst = XRenderCreatePicture (dpy, tmp, format, CPRepeat, &pa); 177 Picture tmp = XRenderCreatePicture (dpy, tmp_pm , format, CPRepeat, &pa);
109 XFreePixmap (dpy, tmp); 178 XFreePixmap (dpy, tmp_pm);
110 179
111 if (kernel && params) 180 if (kernel && params)
112 { 181 {
113 size = rh * 2 + 1; 182 size = rh * 2 + 1;
114 get_gaussian_kernel (rh, size, kernel, params); 183 get_gaussian_kernel (rh, size, kernel, params);
116 XRenderSetPictureFilter (dpy, src, FilterConvolution, params, size+2); 185 XRenderSetPictureFilter (dpy, src, FilterConvolution, params, size+2);
117 XRenderComposite (dpy, 186 XRenderComposite (dpy,
118 PictOpSrc, 187 PictOpSrc,
119 src, 188 src,
120 None, 189 None,
121 dst, 190 tmp,
122 0, 0, 191 0, 0,
123 0, 0, 192 0, 0,
124 0, 0, 193 0, 0,
125 w, h); 194 w, h);
126 195
127 ::swap (src, dst);
128
129 size = rv * 2 + 1; 196 size = rv * 2 + 1;
130 get_gaussian_kernel (rv, size, kernel, params); 197 get_gaussian_kernel (rv, size, kernel, params);
131 ::swap (params[0], params[1]); 198 ::swap (params[0], params[1]);
132 199
133 XRenderSetPictureFilter (dpy, src, FilterConvolution, params, size+2); 200 XRenderSetPictureFilter (dpy, src, FilterConvolution, params, size+2);
134 XRenderComposite (dpy, 201 XRenderComposite (dpy,
135 PictOpSrc, 202 PictOpSrc,
136 src, 203 tmp,
137 None, 204 None,
138 dst, 205 dst,
139 0, 0, 206 0, 0,
140 0, 0, 207 0, 0,
141 0, 0, 208 0, 0,
144 211
145 free (kernel); 212 free (kernel);
146 free (params); 213 free (params);
147 XRenderFreePicture (dpy, src); 214 XRenderFreePicture (dpy, src);
148 XRenderFreePicture (dpy, dst); 215 XRenderFreePicture (dpy, dst);
216 XRenderFreePicture (dpy, tmp);
217
218 return img;
149} 219}
150 220
151static Picture 221static Picture
152create_xrender_mask (Display *dpy, Drawable drawable, Bool argb) 222create_xrender_mask (Display *dpy, Drawable drawable, Bool argb)
153{ 223{
162 232
163 return mask; 233 return mask;
164} 234}
165 235
166void 236void
167rxvt_img::brightness (double r, double g, double b, double a) 237rxvt_img::brightness (unsigned short r, unsigned short g, unsigned short b, unsigned short a)
168{ 238{
169 Display *dpy = s->display->dpy; 239 Display *dpy = s->display->dpy;
170 Picture src = create_xrender_mask (dpy, pm, True); 240 Picture src = create_xrender_mask (dpy, pm, True);
171 Picture dst = XRenderCreatePicture (dpy, pm, format, 0, 0); 241 Picture dst = XRenderCreatePicture (dpy, pm, format, 0, 0);
172 242
173 XRenderColor mask_c; 243 XRenderColor mask_c;
174 mask_c.red = float_to_component (r); 244 mask_c.red = r;
175 mask_c.green = float_to_component (g); 245 mask_c.green = g;
176 mask_c.blue = float_to_component (b); 246 mask_c.blue = b;
177 mask_c.alpha = float_to_component (a); 247 mask_c.alpha = a;
178 XRenderFillRectangle (dpy, PictOpSrc, src, &mask_c, 0, 0, 1, 1); 248 XRenderFillRectangle (dpy, PictOpSrc, src, &mask_c, 0, 0, 1, 1);
179 249
180 XRenderComposite (dpy, PictOpAdd, src, None, dst, 0, 0, 0, 0, 0, 0, w, h); 250 XRenderComposite (dpy, PictOpAdd, src, None, dst, 0, 0, 0, 0, 0, 0, w, h);
251
252 XRenderFreePicture (dpy, src);
253 XRenderFreePicture (dpy, dst);
181} 254}
182 255
183void 256void
184rxvt_img::contrast (double r, double g, double b, double a) 257rxvt_img::contrast (unsigned short r, unsigned short g, unsigned short b, unsigned short a)
185{ 258{
186 if (!(s->display->flags & DISPLAY_HAS_RENDER_MUL)) 259 if (!(s->display->flags & DISPLAY_HAS_RENDER_MUL))
187 return; 260 return;
188 261
189 Display *dpy = s->display->dpy; 262 Display *dpy = s->display->dpy;
190 Picture src = create_xrender_mask (dpy, pm, True); 263 Picture src = create_xrender_mask (dpy, pm, True);
191 Picture dst = XRenderCreatePicture (dpy, pm, format, 0, 0); 264 Picture dst = XRenderCreatePicture (dpy, pm, format, 0, 0);
192 265
193 XRenderColor mask_c; 266 XRenderColor mask_c;
194 mask_c.red = float_to_component (r); 267 mask_c.red = r;
195 mask_c.green = float_to_component (g); 268 mask_c.green = g;
196 mask_c.blue = float_to_component (b); 269 mask_c.blue = b;
197 mask_c.alpha = float_to_component (a); 270 mask_c.alpha = a;
198 XRenderFillRectangle (dpy, PictOpSrc, src, &mask_c, 0, 0, 1, 1); 271 XRenderFillRectangle (dpy, PictOpSrc, src, &mask_c, 0, 0, 1, 1);
199 272
200 XRenderComposite (dpy, PictOpMultiply, src, None, dst, 0, 0, 0, 0, 0, 0, w, h); 273 XRenderComposite (dpy, PictOpMultiply, src, None, dst, 0, 0, 0, 0, 0, 0, w, h);
201}
202 274
203void 275 XRenderFreePicture (dpy, src);
276 XRenderFreePicture (dpy, dst);
277}
278
279bool
204rxvt_img::render (GdkPixbuf *pixbuf, int src_x, int src_y, int width, int height, int dst_x, int dst_y) 280rxvt_img::render_pixbuf (GdkPixbuf *pixbuf, int src_x, int src_y, int width, int height, int dst_x, int dst_y)
205{ 281{
206 //TODO 282 Display *dpy = s->display->dpy;
283
284 if (s->visual->c_class != TrueColor)
285 return false;
286
287 uint32_t red_mask, green_mask, blue_mask, alpha_mask;
288
289 red_mask = (uint32_t)format->direct.redMask << format->direct.red;
290 green_mask = (uint32_t)format->direct.greenMask << format->direct.green;
291 blue_mask = (uint32_t)format->direct.blueMask << format->direct.blue;
292 alpha_mask = (uint32_t)format->direct.alphaMask << format->direct.alpha;
293
294 int width_r = ecb_popcount32 (red_mask);
295 int width_g = ecb_popcount32 (green_mask);
296 int width_b = ecb_popcount32 (blue_mask);
297 int width_a = ecb_popcount32 (alpha_mask);
298
299 if (width_r > 8 || width_g > 8 || width_b > 8 || width_a > 8)
300 return false;
301
302 int sh_r = ecb_ctz32 (red_mask);
303 int sh_g = ecb_ctz32 (green_mask);
304 int sh_b = ecb_ctz32 (blue_mask);
305 int sh_a = ecb_ctz32 (alpha_mask);
306
307 if (width > 32767 || height > 32767)
308 return false;
309
310 XImage *ximage = XCreateImage (dpy, s->visual, format->depth, ZPixmap, 0, 0,
311 width, height, 32, 0);
312 if (!ximage)
313 return false;
314
315 if (height > INT_MAX / ximage->bytes_per_line
316 || !(ximage->data = (char *)malloc (height * ximage->bytes_per_line)))
317 {
318 XDestroyImage (ximage);
319 return false;
320 }
321
322 GC gc = XCreateGC (dpy, pm, 0, 0);
323
324 ximage->byte_order = ecb_big_endian () ? MSBFirst : LSBFirst;
325
326 int rowstride = gdk_pixbuf_get_rowstride (pixbuf);
327 int channels = gdk_pixbuf_get_n_channels (pixbuf);
328 unsigned char *row = gdk_pixbuf_get_pixels (pixbuf) + src_y * rowstride + src_x * channels;
329 char *line = ximage->data;
330
331 for (int y = 0; y < height; y++)
332 {
333 for (int x = 0; x < width; x++)
334 {
335 unsigned char *pixel = row + x * channels;
336 uint32_t value;
337 unsigned char r, g, b, a;
338
339 if (channels == 4)
340 {
341 a = pixel[3];
342 r = pixel[0] * a / 0xff;
343 g = pixel[1] * a / 0xff;
344 b = pixel[2] * a / 0xff;
345 }
346 else
347 {
348 a = 0xff;
349 r = pixel[0];
350 g = pixel[1];
351 b = pixel[2];
352 }
353
354 value = ((r >> (8 - width_r)) << sh_r)
355 | ((g >> (8 - width_g)) << sh_g)
356 | ((b >> (8 - width_b)) << sh_b)
357 | ((a >> (8 - width_a)) << sh_a);
358
359 if (ximage->bits_per_pixel == 32)
360 ((uint32_t *)line)[x] = value;
361 else
362 XPutPixel (ximage, x, y, value);
363 }
364
365 row += rowstride;
366 line += ximage->bytes_per_line;
367 }
368
369 XPutImage (dpy, pm, gc, ximage, 0, 0, dst_x, dst_y, width, height);
370 XDestroyImage (ximage);
371 XFreeGC (dpy, gc);
372
373 return true;
207} 374}
208 375
209rxvt_img * 376rxvt_img *
210rxvt_img::clone () 377rxvt_img::clone ()
211{ 378{
212 GC gc = XCreateGC (s->display->dpy, pm, 0, 0); 379 return new rxvt_img (*this);
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} 380}
218 381
219rxvt_img * 382rxvt_img *
220rxvt_img::transform (int new_width, int new_height, int repeat, double matrix[9]) 383rxvt_img::reify ()
221{ 384{
222 rxvt_img *img = new rxvt_img (s, format, new_width, new_height); 385 rxvt_img *img = new rxvt_img (s, format, 0, 0, w, h);
386 img->alloc ();
387
388 // todo, if x==0 and y==0 and w==real width we could clone
389 // but that involves an rtt to find pixmap width.
223 390
224 Display *dpy = s->display->dpy; 391 Display *dpy = s->display->dpy;
225 XRenderPictureAttributes pa; 392 XRenderPictureAttributes pa;
226 pa.repeat = repeat; 393 pa.repeat = repeat;
227 Picture src = XRenderCreatePicture (dpy, pm, format, CPRepeat, &pa); 394 Picture src = XRenderCreatePicture (dpy, pm, format, CPRepeat, &pa);
228 Picture dst = XRenderCreatePicture (dpy, img->pm, img->format, 0, 0); 395 Picture dst = XRenderCreatePicture (dpy, img->pm, img->format, 0, 0);
396
397 XRenderComposite (dpy, PictOpSrc, src, None, dst, x, y, 0, 0, 0, 0, w, h);
398
399 XRenderFreePicture (dpy, src);
400 XRenderFreePicture (dpy, dst);
401
402 return img;
403}
404
405rxvt_img *
406rxvt_img::sub_rect (int x, int y, int width, int height)
407{
408 rxvt_img *img = clone ();
409
410 img->x += x;
411 img->y += y;
412 img->w = width;
413 img->h = height;
414
415 return img;
416}
417
418rxvt_img *
419rxvt_img::transform (int new_width, int new_height, double matrix[9])
420{
421 rxvt_img *img = new rxvt_img (s, format, 0, 0, new_width, new_height);
422 img->alloc ();
423
424 Display *dpy = s->display->dpy;
425 XRenderPictureAttributes pa;
426 pa.repeat = repeat;
427 Picture src = XRenderCreatePicture (dpy, pm, format, CPRepeat, &pa);
428 Picture dst = XRenderCreatePicture (dpy, img->pm, img->format, 0, 0);
229 429
230 XTransform xfrm; 430 XTransform xfrm;
231 431
232 for (int i = 0; i < 3; ++i) 432 for (int i = 0; i < 3; ++i)
233 for (int j = 0; j < 3; ++j) 433 for (int j = 0; j < 3; ++j)
234 xfrm.matrix [i][j] = XDoubleToFixed (matrix [i * 3 + j]); 434 xfrm.matrix [i][j] = XDoubleToFixed (matrix [i * 3 + j]);
235 435
436 xfrm.matrix [0][2] += XDoubleToFixed (x);//TODO
437 xfrm.matrix [0][3] += XDoubleToFixed (y);
438
439 XRenderSetPictureFilter (dpy, src, "good", 0, 0);
236 XRenderSetPictureTransform (dpy, src, &xfrm); 440 XRenderSetPictureTransform (dpy, src, &xfrm);
237 XRenderComposite (dpy, PictOpSrc, src, None, dst, 0, 0, 0, 0, 0, 0, new_width, new_height); 441 XRenderComposite (dpy, PictOpSrc, src, None, dst, 0, 0, 0, 0, 0, 0, new_width, new_height);
238 442
239 XRenderFreePicture (dpy, src); 443 XRenderFreePicture (dpy, src);
240 XRenderFreePicture (dpy, dst); 444 XRenderFreePicture (dpy, dst);
244 448
245rxvt_img * 449rxvt_img *
246rxvt_img::scale (int new_width, int new_height) 450rxvt_img::scale (int new_width, int new_height)
247{ 451{
248 double matrix[9] = { 452 double matrix[9] = {
249 new_width / (double)w, 0, 0, 453 w / (double)new_width, 0, 0,
250 0, new_height / (double)h, 0, 454 0, h / (double)new_height, 0,
251 0, 0, 1 455 0, 0, 1
252 }; 456 };
253 457
254 return transform (new_width, new_height, RepeatNormal, matrix); 458 return transform (new_width, new_height, matrix);
255} 459}
256 460
257rxvt_img * 461rxvt_img *
462rxvt_img::rotate (int new_width, int new_height, int x, int y, double phi)
463{
464 double s = sin (phi);
465 double c = cos (phi);
466
467 double matrix[9] = {
468 c, -s, -c * x + s * y + x,
469 s, c, -s * x - c * y + y,
470 0, 0, 1
471 };
472
473 return transform (new_width, new_height, matrix);
474}
475
476rxvt_img *
258rxvt_img::convert_to (XRenderPictFormat *new_format) 477rxvt_img::convert_to (XRenderPictFormat *new_format, const rxvt_color &bg)
259{ 478{
479 if (new_format == format)
480 return clone ();
481
260 rxvt_img *img = new rxvt_img (s, new_format, w, h); 482 rxvt_img *img = new rxvt_img (s, new_format, x, y, w, h);
483 img->alloc ();
261 484
262 Display *dpy = s->display->dpy; 485 Display *dpy = s->display->dpy;
263 Picture src = XRenderCreatePicture (dpy, pm, format, 0, 0); 486 Picture src = XRenderCreatePicture (dpy, pm, format, 0, 0);
264 Picture dst = XRenderCreatePicture (dpy, img->pm, new_format, 0, 0); 487 Picture dst = XRenderCreatePicture (dpy, img->pm, new_format, 0, 0);
488 int op = PictOpSrc;
265 489
490 if (format->direct.alphaMask && !new_format->direct.alphaMask)
491 {
492 // does it have to be that complicated
493 rgba c;
494 bg.get (c);
495
496 XRenderColor rc = { c.r, c.g, c.b, 0xffff };
497 XRenderFillRectangle (dpy, PictOpSrc, dst, &rc, 0, 0, w, h);
498
499 op = PictOpOver;
500 }
501
266 XRenderComposite (dpy, PictOpSrc, src, None, dst, 0, 0, 0, 0, 0, 0, w, h); 502 XRenderComposite (dpy, op, src, None, dst, 0, 0, 0, 0, 0, 0, w, h);
267 503
268 XRenderFreePicture (dpy, src);
269 XRenderFreePicture (dpy, dst); 504 XRenderFreePicture (dpy, src);
505 XRenderFreePicture (dpy, dst);
270 506
507 return img;
508}
509
510rxvt_img *
511rxvt_img::blend (rxvt_img *img, double factor)
512{
513 rxvt_img *img2 = clone ();
514 Display *dpy = s->display->dpy;
515 Picture src = XRenderCreatePicture (dpy, img->pm, img->format, 0, 0);
516 Picture dst = XRenderCreatePicture (dpy, img2->pm, img2->format, 0, 0);
517 Picture mask = create_xrender_mask (dpy, img->pm, False);
518
519 XRenderColor mask_c;
520
521 mask_c.alpha = float_to_component (factor);
522 mask_c.red =
523 mask_c.green =
524 mask_c.blue = 0;
525 XRenderFillRectangle (dpy, PictOpSrc, mask, &mask_c, 0, 0, 1, 1);
526
527 XRenderComposite (dpy, PictOpOver, src, mask, dst, 0, 0, 0, 0, 0, 0, w, h);
528
529 XRenderFreePicture (dpy, src);
530 XRenderFreePicture (dpy, dst);
531 XRenderFreePicture (dpy, mask);
532
271 return img; 533 return img2;
272} 534}
273 535
274#endif 536#endif
275 537

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines