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

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines