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.18 by sf-exg, Tue Jun 5 12:30:37 2012 UTC vs.
Revision 1.46 by root, Thu Jun 7 18:07:42 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_pixbuf (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);
288
289 XRenderFreePicture (dpy, src);
290 XRenderFreePicture (dpy, dst);
201} 291}
202 292
203bool 293bool
204rxvt_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)
205{ 295{
249 339
250 int rowstride = gdk_pixbuf_get_rowstride (pixbuf); 340 int rowstride = gdk_pixbuf_get_rowstride (pixbuf);
251 int channels = gdk_pixbuf_get_n_channels (pixbuf); 341 int channels = gdk_pixbuf_get_n_channels (pixbuf);
252 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;
253 char *line = ximage->data; 343 char *line = ximage->data;
254
255 rgba c (0, 0, 0);
256
257 if (channels == 4 && alpha_mask == 0)
258 {
259 //pix_colors[Color_bg].get (c);
260 //TODO
261 c.r = 0xffff; c.g = 0xc0c0; c.b = 0xcbcb;//D
262 c.r >>= 8;
263 c.g >>= 8;
264 c.b >>= 8;
265 }
266 344
267 for (int y = 0; y < height; y++) 345 for (int y = 0; y < height; y++)
268 { 346 {
269 for (int x = 0; x < width; x++) 347 for (int x = 0; x < width; x++)
270 { 348 {
273 unsigned char r, g, b, a; 351 unsigned char r, g, b, a;
274 352
275 if (channels == 4) 353 if (channels == 4)
276 { 354 {
277 a = pixel[3]; 355 a = pixel[3];
278 r = (pixel[0] * a + c.r * (0xff - a)) / 0xff; 356 r = pixel[0] * a / 0xff;
279 g = (pixel[1] * a + c.g * (0xff - a)) / 0xff; 357 g = pixel[1] * a / 0xff;
280 b = (pixel[2] * a + c.b * (0xff - a)) / 0xff; 358 b = pixel[2] * a / 0xff;
281 } 359 }
282 else 360 else
283 { 361 {
284 a = 0xff; 362 a = 0xff;
285 r = pixel[0]; 363 r = pixel[0];
310} 388}
311 389
312rxvt_img * 390rxvt_img *
313rxvt_img::clone () 391rxvt_img::clone ()
314{ 392{
315 GC gc = XCreateGC (s->display->dpy, pm, 0, 0); 393 return new rxvt_img (*this);
316 Pixmap pm2 = XCreatePixmap (s->display->dpy, pm, w, h, format->depth);
317 XCopyArea (s->display->dpy, pm, pm2, gc, 0, 0, w, h, 0, 0);
318 XFreeGC (s->display->dpy, gc);
319 return new rxvt_img (s, format, w, h, pm2);
320} 394}
321 395
322rxvt_img *
323rxvt_img::transform (int new_width, int new_height, int repeat, double matrix[9])
324{
325 rxvt_img *img = new rxvt_img (s, format, new_width, new_height);
326 396
397static XRenderPictFormat *
398find_alpha_format_for (Display *dpy, XRenderPictFormat *format)
399{
400 if (format->direct.alphaMask)
401 return format; // already has alpha
402
403 // try to find a suitable alpha format, one bit alpha is enough for our purposes
404 if (format->type == PictTypeDirect)
405 for (int n = 0; XRenderPictFormat *f = XRenderFindFormat (dpy, 0, 0, n); ++n)
406 if (f->direct.alphaMask
407 && f->type == PictTypeDirect
408 && ecb_popcount32 (f->direct.redMask ) >= ecb_popcount32 (format->direct.redMask )
409 && ecb_popcount32 (f->direct.greenMask) >= ecb_popcount32 (format->direct.greenMask)
410 && ecb_popcount32 (f->direct.blueMask ) >= ecb_popcount32 (format->direct.blueMask ))
411 return f;
412
413 // should be a very good fallback
414 return XRenderFindStandardFormat (dpy, PictStandardARGB32);
415}
416
417rxvt_img *
418rxvt_img::reify ()
419{
420 if (x == 0 && y == 0 && w == ref->w && h == ref->h)
421 return clone ();
422
327 Display *dpy = s->display->dpy; 423 Display *dpy = s->display->dpy;
328 XRenderPictureAttributes pa; 424
329 pa.repeat = repeat; 425 bool alpha = !format->direct.alphaMask
330 Picture src = XRenderCreatePicture (dpy, pm, format, CPRepeat, &pa); 426 && (x || y)
427 && repeat == RepeatNone;
428
429 rxvt_img *img = new rxvt_img (s, alpha ? find_alpha_format_for (dpy, format) : format, 0, 0, w, h, repeat);
430 img->alloc ();
431
432 Picture src = src_picture ();
331 Picture dst = XRenderCreatePicture (dpy, img->pm, img->format, 0, 0); 433 Picture dst = XRenderCreatePicture (dpy, img->pm, img->format, 0, 0);
434
435 if (alpha)
436 {
437 XRenderColor rc = { 0, 0, 0, 0 };
438 XRenderFillRectangle (dpy, PictOpSrc, dst, &rc, 0, 0, w, h);//TODO: split into four fillrectangles
439 XRenderComposite (dpy, PictOpSrc, src, None, dst, 0, 0, 0, 0, -x, -y, ref->w, ref->h);
440 }
441 else
442 XRenderComposite (dpy, PictOpSrc, src, None, dst, x, y, 0, 0, 0, 0, w, h);
443
444 XRenderFreePicture (dpy, src);
445 XRenderFreePicture (dpy, dst);
446
447 return img;
448}
449
450rxvt_img *
451rxvt_img::sub_rect (int x, int y, int width, int height)
452{
453 rxvt_img *img = clone ();
454
455 img->x += x;
456 img->y += y;
457
458 if (w != width || h != height)
459 {
460 img->w = width;
461 img->h = height;
462
463 rxvt_img *img2 = img->reify ();
464 delete img;
465 img = img2;
466 }
467
468 return img;
469}
470
471rxvt_img *
472rxvt_img::transform (int new_width, int new_height, double matrix[9])
473{
474 rxvt_img *img = new rxvt_img (s, format, 0, 0, new_width, new_height, repeat);
475 img->alloc ();
476
477 Display *dpy = s->display->dpy;
478 Picture src = src_picture ();
479 Picture dst = XRenderCreatePicture (dpy, img->pm, img->format, 0, 0);
332 480
333 XTransform xfrm; 481 XTransform xfrm;
334 482
335 for (int i = 0; i < 3; ++i) 483 for (int i = 0; i < 3; ++i)
336 for (int j = 0; j < 3; ++j) 484 for (int j = 0; j < 3; ++j)
337 xfrm.matrix [i][j] = XDoubleToFixed (matrix [i * 3 + j]); 485 xfrm.matrix [i][j] = XDoubleToFixed (matrix [i * 3 + j]);
338 486
487#if 0
488 xfrm.matrix [0][2] -= XDoubleToFixed (x);//TODO
489 xfrm.matrix [1][2] -= XDoubleToFixed (y);
490#endif
491
339 XRenderSetPictureFilter (dpy, src, "good", 0, 0); 492 XRenderSetPictureFilter (dpy, src, "good", 0, 0);
340 XRenderSetPictureTransform (dpy, src, &xfrm); 493 XRenderSetPictureTransform (dpy, src, &xfrm);
341 XRenderComposite (dpy, PictOpSrc, src, None, dst, 0, 0, 0, 0, 0, 0, new_width, new_height); 494 XRenderComposite (dpy, PictOpSrc, src, None, dst, 0, 0, 0, 0, 0, 0, new_width, new_height);
342 495
343 XRenderFreePicture (dpy, src); 496 XRenderFreePicture (dpy, src);
347} 500}
348 501
349rxvt_img * 502rxvt_img *
350rxvt_img::scale (int new_width, int new_height) 503rxvt_img::scale (int new_width, int new_height)
351{ 504{
505 if (w == new_width && h == new_height)
506 return clone ();
507
352 double matrix[9] = { 508 double matrix[9] = {
353 w / (double)new_width, 0, 0, 509 w / (double)new_width, 0, 0,
354 0, h / (double)new_height, 0, 510 0, h / (double)new_height, 0,
355 0, 0, 1 511 0, 0, 1
356 }; 512 };
357 513
514 int old_repeat_mode = repeat;
515 repeat = RepeatPad; // not right, but xrender can't proeprly scale it seems
516
358 return transform (new_width, new_height, RepeatNormal, matrix); 517 rxvt_img *img = transform (new_width, new_height, matrix);
359}
360 518
519 repeat = old_repeat_mode;
520 img->repeat = repeat;
521
522 return img;
523}
524
361rxvt_img * 525rxvt_img *
362rxvt_img::rotate (int new_width, int new_height, int repeat, int x, int y, double phi) 526rxvt_img::rotate (int new_width, int new_height, int x, int y, double phi)
363{ 527{
364 double s = sin (phi); 528 double s = sin (phi);
365 double c = cos (phi); 529 double c = cos (phi);
366 530
367 double matrix[9] = { 531 double matrix[9] = {
368 c, -s, -c * x + s * y + x, 532 c, -s, -c * x + s * y + x,
369 s, c, -s * x - c * y + y, 533 s, c, -s * x - c * y + y,
370 0, 0, 1 534 0, 0, 1
371 }; 535 };
372 536
373 return transform (new_width, new_height, repeat, matrix); 537 return transform (new_width, new_height, matrix);
374} 538}
375 539
376rxvt_img * 540rxvt_img *
377rxvt_img::convert_to (XRenderPictFormat *new_format) 541rxvt_img::convert_format (XRenderPictFormat *new_format, const rxvt_color &bg)
378{ 542{
543 if (new_format == format)
544 return clone ();
545
379 rxvt_img *img = new rxvt_img (s, new_format, w, h); 546 rxvt_img *img = new rxvt_img (s, new_format, x, y, w, h, repeat);
547 img->alloc ();
380 548
381 Display *dpy = s->display->dpy; 549 Display *dpy = s->display->dpy;
382 Picture src = XRenderCreatePicture (dpy, pm, format, 0, 0); 550 Picture src = src_picture ();
383 Picture dst = XRenderCreatePicture (dpy, img->pm, new_format, 0, 0); 551 Picture dst = XRenderCreatePicture (dpy, img->pm, new_format, 0, 0);
552 int op = PictOpSrc;
384 553
554 if (format->direct.alphaMask && !new_format->direct.alphaMask)
555 {
556 // does it have to be that complicated
557 rgba c;
558 bg.get (c);
559
560 XRenderColor rc = { c.r, c.g, c.b, 0xffff };
561 XRenderFillRectangle (dpy, PictOpSrc, dst, &rc, 0, 0, w, h);
562
563 op = PictOpOver;
564 }
565
385 XRenderComposite (dpy, PictOpSrc, src, None, dst, 0, 0, 0, 0, 0, 0, w, h); 566 XRenderComposite (dpy, op, src, None, dst, 0, 0, 0, 0, 0, 0, w, h);
386 567
387 XRenderFreePicture (dpy, src); 568 XRenderFreePicture (dpy, src);
388 XRenderFreePicture (dpy, dst); 569 XRenderFreePicture (dpy, dst);
389 570
390 return img; 571 return img;
391} 572}
392 573
574rxvt_img *
575rxvt_img::blend (rxvt_img *img, double factor)
576{
577 rxvt_img *img2 = clone ();
578 Display *dpy = s->display->dpy;
579 Picture src = img->src_picture ();
580 Picture dst = XRenderCreatePicture (dpy, img2->pm, img2->format, 0, 0);
581 Picture mask = create_xrender_mask (dpy, img->pm, False);
582
583 XRenderColor mask_c;
584
585 mask_c.alpha = float_to_component (factor);
586 mask_c.red =
587 mask_c.green =
588 mask_c.blue = 0;
589 XRenderFillRectangle (dpy, PictOpSrc, mask, &mask_c, 0, 0, 1, 1);
590
591 XRenderComposite (dpy, PictOpOver, src, mask, dst, 0, 0, 0, 0, 0, 0, w, h);
592
593 XRenderFreePicture (dpy, src);
594 XRenderFreePicture (dpy, dst);
595 XRenderFreePicture (dpy, mask);
596
597 return img2;
598}
599
393#endif 600#endif
394 601

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines