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.21 by sf-exg, Tue Jun 5 14:59:44 2012 UTC vs.
Revision 1.43 by sf-exg, Thu Jun 7 13:02:50 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{
18} 23}
24#endif
19 25
20rxvt_img * 26rxvt_img *
21rxvt_img::new_from_root (rxvt_screen *s) 27rxvt_img::new_from_root (rxvt_screen *s)
22{ 28{
23 Display *dpy = s->display->dpy; 29 Display *dpy = s->display->dpy;
37 return 0; 43 return 0;
38 44
39 rxvt_img *img = new rxvt_img ( 45 rxvt_img *img = new rxvt_img (
40 s, 46 s,
41 XRenderFindVisualFormat (dpy, DefaultVisual (dpy, s->display->screen)), 47 XRenderFindVisualFormat (dpy, DefaultVisual (dpy, s->display->screen)),
48 0,
49 0,
42 root_pm_w, 50 root_pm_w,
43 root_pm_h, 51 root_pm_h
44 root_pixmap
45 ); 52 );
46 53
47 img->shared = true; 54 img->pm = root_pixmap;
55 img->ref = new pixref (root_pm_w, root_pm_h);
56 img->ref->ours = false;
48 57
49 return img; 58 return img;
50} 59}
51 60
52rxvt_img * 61rxvt_img *
59 rxvt_fatal ("rxvt_img::new_from_file: %s\n", err->message); 68 rxvt_fatal ("rxvt_img::new_from_file: %s\n", err->message);
60 69
61 rxvt_img *img = new rxvt_img ( 70 rxvt_img *img = new rxvt_img (
62 s, 71 s,
63 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,
64 gdk_pixbuf_get_width (pb), 75 gdk_pixbuf_get_width (pb),
65 gdk_pixbuf_get_height (pb) 76 gdk_pixbuf_get_height (pb)
66 ); 77 );
67 78 img->alloc ();
68 img->render_pixbuf (pb, 0, 0, img->w, img->h, 0, 0); 79 img->render_pixbuf (pb, 0, 0, img->w, img->h, 0, 0);
69 80
81 g_object_unref (pb);
82
83 return img;
84}
85
86void
87rxvt_img::destroy ()
88{
89 if (--ref->cnt)
70 return img; 90 return;
91
92 if (pm && ref->ours)
93 XFreePixmap (s->display->dpy, pm);
94
95 delete ref;
71} 96}
72 97
73rxvt_img::~rxvt_img () 98rxvt_img::~rxvt_img ()
74{ 99{
75 if (!shared) 100 destroy ();
76 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;
77} 120}
78 121
79void 122void
80rxvt_img::unshare () 123rxvt_img::unshare ()
81{ 124{
82 if (!shared) 125 if (ref->cnt == 1 && ref->ours)
83 return; 126 return;
84 127
85 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);
86 133
87 ::swap (pm , img->pm); 134 destroy ();
88 ::swap (shared, img->shared);
89 135
90 delete img; 136 pm = pm2;
137 ref = new pixref (ref->w, ref->h);
91} 138}
92 139
93void 140void
94rxvt_img::fill (const rxvt_color &c) 141rxvt_img::fill (const rxvt_color &c)
95{ 142{
119 166
120 for (int i = 0; i < width; i++) 167 for (int i = 0; i < width; i++)
121 params[i+2] = XDoubleToFixed (kernel[i] / sum); 168 params[i+2] = XDoubleToFixed (kernel[i] / sum);
122} 169}
123 170
124void 171rxvt_img *
125rxvt_img::blur (int rh, int rv) 172rxvt_img::blur (int rh, int rv)
126{ 173{
127 if (!(s->display->flags & DISPLAY_HAS_RENDER_CONV)) 174 if (!(s->display->flags & DISPLAY_HAS_RENDER_CONV))
128 return; 175 return clone ();
129 176
130 Display *dpy = s->display->dpy; 177 Display *dpy = s->display->dpy;
131 int size = max (rh, rv) * 2 + 1; 178 int size = max (rh, rv) * 2 + 1;
132 double *kernel = (double *)malloc (size * sizeof (double)); 179 double *kernel = (double *)malloc (size * sizeof (double));
133 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 ();
134 185
135 XRenderPictureAttributes pa; 186 XRenderPictureAttributes pa;
136
137 pa.repeat = RepeatPad; 187 pa.repeat = RepeatPad;
138 Picture src = XRenderCreatePicture (dpy, pm , format, CPRepeat, &pa); 188 Picture dst = XRenderCreatePicture (dpy, img->pm, format, CPRepeat, &pa);
189
139 Pixmap tmp = XCreatePixmap (dpy, pm, w, h, format->depth); 190 Pixmap tmp_pm = XCreatePixmap (dpy, pm, w, h, format->depth);
140 Picture dst = XRenderCreatePicture (dpy, tmp, format, CPRepeat, &pa); 191 Picture tmp = XRenderCreatePicture (dpy, tmp_pm , format, CPRepeat, &pa);
141 XFreePixmap (dpy, tmp); 192 XFreePixmap (dpy, tmp_pm);
142 193
143 if (kernel && params) 194 if (kernel && params)
144 { 195 {
145 size = rh * 2 + 1; 196 size = rh * 2 + 1;
146 get_gaussian_kernel (rh, size, kernel, params); 197 get_gaussian_kernel (rh, size, kernel, params);
147 198
148 XRenderSetPictureFilter (dpy, src, FilterConvolution, params, size+2); 199 XRenderSetPictureFilter (dpy, src, FilterConvolution, params, size+2);
149 XRenderComposite (dpy, 200 XRenderComposite (dpy,
150 PictOpSrc, 201 PictOpSrc,
151 src, 202 src,
203 None,
204 tmp,
205 0, 0,
206 0, 0,
207 0, 0,
208 w, h);
209
210 size = rv * 2 + 1;
211 get_gaussian_kernel (rv, size, kernel, params);
212 ::swap (params[0], params[1]);
213
214 XRenderSetPictureFilter (dpy, src, FilterConvolution, params, size+2);
215 XRenderComposite (dpy,
216 PictOpSrc,
217 tmp,
152 None, 218 None,
153 dst, 219 dst,
154 0, 0, 220 0, 0,
155 0, 0, 221 0, 0,
156 0, 0, 222 0, 0,
157 w, h); 223 w, h);
158
159 ::swap (src, dst);
160
161 size = rv * 2 + 1;
162 get_gaussian_kernel (rv, size, kernel, params);
163 ::swap (params[0], params[1]);
164
165 XRenderSetPictureFilter (dpy, src, FilterConvolution, params, size+2);
166 XRenderComposite (dpy,
167 PictOpSrc,
168 src,
169 None,
170 dst,
171 0, 0,
172 0, 0,
173 0, 0,
174 w, h);
175 } 224 }
176 225
177 free (kernel); 226 free (kernel);
178 free (params); 227 free (params);
179 XRenderFreePicture (dpy, src); 228 XRenderFreePicture (dpy, src);
180 XRenderFreePicture (dpy, dst); 229 XRenderFreePicture (dpy, dst);
230 XRenderFreePicture (dpy, tmp);
231
232 return img;
181} 233}
182 234
183static Picture 235static Picture
184create_xrender_mask (Display *dpy, Drawable drawable, Bool argb) 236create_xrender_mask (Display *dpy, Drawable drawable, Bool argb)
185{ 237{
194 246
195 return mask; 247 return mask;
196} 248}
197 249
198void 250void
199rxvt_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)
200{ 252{
201 Display *dpy = s->display->dpy; 253 Display *dpy = s->display->dpy;
202 Picture src = create_xrender_mask (dpy, pm, True); 254 Picture src = create_xrender_mask (dpy, pm, True);
203 Picture dst = XRenderCreatePicture (dpy, pm, format, 0, 0); 255 Picture dst = XRenderCreatePicture (dpy, pm, format, 0, 0);
204 256
205 XRenderColor mask_c; 257 XRenderColor mask_c;
206 mask_c.red = float_to_component (r); 258 mask_c.red = r;
207 mask_c.green = float_to_component (g); 259 mask_c.green = g;
208 mask_c.blue = float_to_component (b); 260 mask_c.blue = b;
209 mask_c.alpha = float_to_component (a); 261 mask_c.alpha = a;
210 XRenderFillRectangle (dpy, PictOpSrc, src, &mask_c, 0, 0, 1, 1); 262 XRenderFillRectangle (dpy, PictOpSrc, src, &mask_c, 0, 0, 1, 1);
211 263
212 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);
213} 268}
214 269
215void 270void
216rxvt_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)
217{ 272{
218 if (!(s->display->flags & DISPLAY_HAS_RENDER_MUL)) 273 if (!(s->display->flags & DISPLAY_HAS_RENDER_MUL))
219 return; 274 return;
220 275
221 Display *dpy = s->display->dpy; 276 Display *dpy = s->display->dpy;
222 Picture src = create_xrender_mask (dpy, pm, True); 277 Picture src = create_xrender_mask (dpy, pm, True);
223 Picture dst = XRenderCreatePicture (dpy, pm, format, 0, 0); 278 Picture dst = XRenderCreatePicture (dpy, pm, format, 0, 0);
224 279
225 XRenderColor mask_c; 280 XRenderColor mask_c;
226 mask_c.red = float_to_component (r); 281 mask_c.red = r;
227 mask_c.green = float_to_component (g); 282 mask_c.green = g;
228 mask_c.blue = float_to_component (b); 283 mask_c.blue = b;
229 mask_c.alpha = float_to_component (a); 284 mask_c.alpha = a;
230 XRenderFillRectangle (dpy, PictOpSrc, src, &mask_c, 0, 0, 1, 1); 285 XRenderFillRectangle (dpy, PictOpSrc, src, &mask_c, 0, 0, 1, 1);
231 286
232 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);
288
289 XRenderFreePicture (dpy, src);
290 XRenderFreePicture (dpy, dst);
233} 291}
234 292
235bool 293bool
236rxvt_img::render_pixbuf (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)
237{ 295{
281 339
282 int rowstride = gdk_pixbuf_get_rowstride (pixbuf); 340 int rowstride = gdk_pixbuf_get_rowstride (pixbuf);
283 int channels = gdk_pixbuf_get_n_channels (pixbuf); 341 int channels = gdk_pixbuf_get_n_channels (pixbuf);
284 unsigned char *row = gdk_pixbuf_get_pixels (pixbuf) + src_y * rowstride + src_x * channels; 342 unsigned char *row = gdk_pixbuf_get_pixels (pixbuf) + src_y * rowstride + src_x * channels;
285 char *line = ximage->data; 343 char *line = ximage->data;
286
287 rgba c (0, 0, 0);
288
289 if (channels == 4 && alpha_mask == 0)
290 {
291 //pix_colors[Color_bg].get (c);
292 //TODO
293 c.r = 0xffff; c.g = 0xc0c0; c.b = 0xcbcb;//D
294 c.r >>= 8;
295 c.g >>= 8;
296 c.b >>= 8;
297 }
298 344
299 for (int y = 0; y < height; y++) 345 for (int y = 0; y < height; y++)
300 { 346 {
301 for (int x = 0; x < width; x++) 347 for (int x = 0; x < width; x++)
302 { 348 {
305 unsigned char r, g, b, a; 351 unsigned char r, g, b, a;
306 352
307 if (channels == 4) 353 if (channels == 4)
308 { 354 {
309 a = pixel[3]; 355 a = pixel[3];
310 r = (pixel[0] * a + c.r * (0xff - a)) / 0xff; 356 r = pixel[0] * a / 0xff;
311 g = (pixel[1] * a + c.g * (0xff - a)) / 0xff; 357 g = pixel[1] * a / 0xff;
312 b = (pixel[2] * a + c.b * (0xff - a)) / 0xff; 358 b = pixel[2] * a / 0xff;
313 } 359 }
314 else 360 else
315 { 361 {
316 a = 0xff; 362 a = 0xff;
317 r = pixel[0]; 363 r = pixel[0];
342} 388}
343 389
344rxvt_img * 390rxvt_img *
345rxvt_img::clone () 391rxvt_img::clone ()
346{ 392{
347 rxvt_img *img = new rxvt_img (s, format, w, h); 393 return new rxvt_img (*this);
348
349 GC gc = XCreateGC (s->display->dpy, pm, 0, 0);
350 XCopyArea (s->display->dpy, pm, img->pm, gc, 0, 0, w, h, 0, 0);
351 XFreeGC (s->display->dpy, gc);
352
353 return img;
354} 394}
355 395
356rxvt_img * 396rxvt_img *
357rxvt_img::sub_rect (int x, int y, int width, int height, int repeat) 397rxvt_img::reify ()
358{ 398{
359 rxvt_img *img = new rxvt_img (s, format, width, height); 399 if (x == 0 && y == 0 && w == ref->w && h == ref->h)
400 return clone ();
360 401
361 Display *dpy = s->display->dpy; 402 Display *dpy = s->display->dpy;
362 XRenderPictureAttributes pa; 403
363 pa.repeat = repeat; 404 bool alpha = !format->direct.alphaMask
364 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 ();
365 Picture dst = XRenderCreatePicture (dpy, img->pm, img->format, 0, 0); 412 Picture dst = XRenderCreatePicture (dpy, img->pm, img->format, 0, 0);
366 413
414 if (alpha)
415 {
416 XRenderColor rc = { 0, 0, 0, 0 };
417 XRenderFillRectangle (dpy, PictOpSrc, dst, &rc, 0, 0, w, h);
418 XRenderComposite (dpy, PictOpSrc, src, None, dst, 0, 0, 0, 0, -x, -y, ref->w, ref->h);
419 }
420 else
367 XRenderComposite (dpy, PictOpSrc, src, None, dst, x, y, 0, 0, 0, 0, width, height); 421 XRenderComposite (dpy, PictOpSrc, src, None, dst, x, y, 0, 0, 0, 0, w, h);
368 422
369 XRenderFreePicture (dpy, src);
370 XRenderFreePicture (dpy, dst); 423 XRenderFreePicture (dpy, src);
424 XRenderFreePicture (dpy, dst);
371 425
372 return img; 426 return img;
373} 427}
374 428
375rxvt_img * 429rxvt_img *
430rxvt_img::sub_rect (int x, int y, int width, int height)
431{
432 rxvt_img *img = clone ();
433
434 img->x += x;
435 img->y += y;
436
437 if (w != width || h != height)
438 {
439 img->w = width;
440 img->h = height;
441
442 rxvt_img *img2 = img->reify ();
443 delete img;
444 img = img2;
445 }
446
447 return img;
448}
449
450rxvt_img *
376rxvt_img::transform (int new_width, int new_height, double matrix[9], int repeat) 451rxvt_img::transform (int new_width, int new_height, double matrix[9])
377{ 452{
378 rxvt_img *img = new rxvt_img (s, format, new_width, new_height); 453 rxvt_img *img = new rxvt_img (s, format, 0, 0, new_width, new_height, repeat);
454 img->alloc ();
379 455
380 Display *dpy = s->display->dpy; 456 Display *dpy = s->display->dpy;
381 XRenderPictureAttributes pa; 457 Picture src = src_picture ();
382 pa.repeat = repeat;
383 Picture src = XRenderCreatePicture (dpy, pm, format, CPRepeat, &pa);
384 Picture dst = XRenderCreatePicture (dpy, img->pm, img->format, 0, 0); 458 Picture dst = XRenderCreatePicture (dpy, img->pm, img->format, 0, 0);
385 459
386 XTransform xfrm; 460 XTransform xfrm;
387 461
388 for (int i = 0; i < 3; ++i) 462 for (int i = 0; i < 3; ++i)
389 for (int j = 0; j < 3; ++j) 463 for (int j = 0; j < 3; ++j)
390 xfrm.matrix [i][j] = XDoubleToFixed (matrix [i * 3 + j]); 464 xfrm.matrix [i][j] = XDoubleToFixed (matrix [i * 3 + j]);
391 465
466 xfrm.matrix [0][2] += XDoubleToFixed (x);//TODO
467 xfrm.matrix [0][3] += XDoubleToFixed (y);
468
392 XRenderSetPictureFilter (dpy, src, "good", 0, 0); 469 XRenderSetPictureFilter (dpy, src, "good", 0, 0);
393 XRenderSetPictureTransform (dpy, src, &xfrm); 470 XRenderSetPictureTransform (dpy, src, &xfrm);
394 XRenderComposite (dpy, PictOpSrc, src, None, dst, 0, 0, 0, 0, 0, 0, new_width, new_height); 471 XRenderComposite (dpy, PictOpSrc, src, None, dst, 0, 0, 0, 0, 0, 0, new_width, new_height);
395 472
396 XRenderFreePicture (dpy, src); 473 XRenderFreePicture (dpy, src);
400} 477}
401 478
402rxvt_img * 479rxvt_img *
403rxvt_img::scale (int new_width, int new_height) 480rxvt_img::scale (int new_width, int new_height)
404{ 481{
482 if (w == new_width && h == new_height)
483 return clone ();
484
405 double matrix[9] = { 485 double matrix[9] = {
406 w / (double)new_width, 0, 0, 486 w / (double)new_width, 0, 0,
407 0, h / (double)new_height, 0, 487 0, h / (double)new_height, 0,
408 0, 0, 1 488 0, 0, 1
409 }; 489 };
410 490
491 int old_repeat_mode = repeat;
492 repeat = RepeatPad; // not right, but xrender can't proeprly scale it seems
493
411 return transform (new_width, new_height, matrix); 494 rxvt_img *img = transform (new_width, new_height, matrix);
412}
413 495
496 repeat = old_repeat_mode;
497 img->repeat = repeat;
498
499 return img;
500}
501
414rxvt_img * 502rxvt_img *
415rxvt_img::rotate (int new_width, int new_height, int x, int y, double phi, int repeat) 503rxvt_img::rotate (int new_width, int new_height, int x, int y, double phi)
416{ 504{
417 double s = sin (phi); 505 double s = sin (phi);
418 double c = cos (phi); 506 double c = cos (phi);
419 507
420 double matrix[9] = { 508 double matrix[9] = {
421 c, -s, -c * x + s * y + x, 509 c, -s, -c * x + s * y + x,
422 s, c, -s * x - c * y + y, 510 s, c, -s * x - c * y + y,
423 0, 0, 1 511 0, 0, 1
424 }; 512 };
425 513
426 return transform (new_width, new_height, matrix, repeat); 514 return transform (new_width, new_height, matrix);
427} 515}
428 516
429rxvt_img * 517rxvt_img *
430rxvt_img::convert_to (XRenderPictFormat *new_format) 518rxvt_img::convert_to (XRenderPictFormat *new_format, const rxvt_color &bg)
431{ 519{
520 if (new_format == format)
521 return clone ();
522
432 rxvt_img *img = new rxvt_img (s, new_format, w, h); 523 rxvt_img *img = new rxvt_img (s, new_format, 0, 0, w, h, repeat);
524 img->alloc ();
433 525
526 printf ("convert %d to %d\n", format->direct.alphaMask, new_format->direct.alphaMask);//D
527
434 Display *dpy = s->display->dpy; 528 Display *dpy = s->display->dpy;
435 Picture src = XRenderCreatePicture (dpy, pm, format, 0, 0); 529 Picture src = src_picture ();
436 Picture dst = XRenderCreatePicture (dpy, img->pm, new_format, 0, 0); 530 Picture dst = XRenderCreatePicture (dpy, img->pm, new_format, 0, 0);
531 int op = PictOpSrc;
437 532
533 if (format->direct.alphaMask && !new_format->direct.alphaMask)
534 {
535 // does it have to be that complicated
536 rgba c;
537 bg.get (c);
538
539 XRenderColor rc = { c.r, c.g, c.b, 0xffff };
540 XRenderFillRectangle (dpy, PictOpSrc, dst, &rc, 0, 0, w, h);
541
542 op = PictOpOver;
543 }
544
438 XRenderComposite (dpy, PictOpSrc, src, None, dst, 0, 0, 0, 0, 0, 0, w, h); 545 XRenderComposite (dpy, op, src, None, dst, 0, 0, 0, 0, 0, 0, w, h);
439 546
440 XRenderFreePicture (dpy, src);
441 XRenderFreePicture (dpy, dst); 547 XRenderFreePicture (dpy, src);
548 XRenderFreePicture (dpy, dst);
442 549
550 return img;
551}
552
553rxvt_img *
554rxvt_img::blend (rxvt_img *img, double factor)
555{
556 rxvt_img *img2 = clone ();
557 Display *dpy = s->display->dpy;
558 Picture src = img->src_picture ();
559 Picture dst = XRenderCreatePicture (dpy, img2->pm, img2->format, 0, 0);
560 Picture mask = create_xrender_mask (dpy, img->pm, False);
561
562 XRenderColor mask_c;
563
564 mask_c.alpha = float_to_component (factor);
565 mask_c.red =
566 mask_c.green =
567 mask_c.blue = 0;
568 XRenderFillRectangle (dpy, PictOpSrc, mask, &mask_c, 0, 0, 1, 1);
569
570 XRenderComposite (dpy, PictOpOver, src, mask, dst, 0, 0, 0, 0, 0, 0, w, h);
571
572 XRenderFreePicture (dpy, src);
573 XRenderFreePicture (dpy, dst);
574 XRenderFreePicture (dpy, mask);
575
443 return img; 576 return img2;
444} 577}
445 578
446#endif 579#endif
447 580

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines