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.49 by root, Thu Jun 7 19:24:13 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;
59}
60
61rxvt_img *
62rxvt_img::new_from_pixbuf (rxvt_screen *s, GdkPixbuf *pb)
63{
64 Display *dpy = s->display->dpy;
65
66 int width = gdk_pixbuf_get_width (pb);
67 int height = gdk_pixbuf_get_height (pb);
68
69 if (width > 32767 || height > 32767) // well, we *could* upload in chunks
70 rxvt_fatal ("rxvt_img::new_from_pixbuf: image too big (maximum size 32768x32768).\n");
71
72 // since we require rgb24/argb32 formats from xrender we assume
73 // that both 24 and 32 bpp MUST be supported by any screen that supports xrender
74 int depth = gdk_pixbuf_get_has_alpha (pb) ? 32 : 24;
75
76 XImage xi;
77
78 xi.width = width;
79 xi.height = height;
80 xi.xoffset = 0;
81 xi.format = ZPixmap;
82 xi.byte_order = MSBFirst; // maybe go for host byte order, because servers are usually local?
83 xi.bitmap_unit = 32;
84 xi.bitmap_bit_order = MSBFirst;
85 xi.bitmap_pad = BitmapPad (dpy);
86 xi.depth = depth;
87 xi.bytes_per_line = 0;
88 xi.bits_per_pixel = 32;
89 xi.red_mask = 0x00ff0000;
90 xi.green_mask = 0x0000ff00;
91 xi.blue_mask = 0x000000ff;
92
93 if (!XInitImage (&xi))
94 rxvt_fatal ("unable to initialise ximage, please report.\n");
95
96 if (height > INT_MAX / xi.bytes_per_line)
97 rxvt_fatal ("rxvt_img::new_from_pixbuf: image too big for Xlib.\n");
98
99 xi.data = (char *)rxvt_malloc (height * xi.bytes_per_line);
100
101 int rowstride = gdk_pixbuf_get_rowstride (pb);
102
103 assert (3 + (depth == 32) == gdk_pixbuf_get_n_channels (pb));
104 unsigned char *row = gdk_pixbuf_get_pixels (pb);
105 char *line = xi.data;
106
107 for (int y = 0; y < height; y++)
108 {
109 unsigned char r, g, b, a;
110 unsigned char *data = row;
111
112 if (depth == 24)
113 for (int x = 0; x < width; x++)
114 {
115 r = *data++;
116 g = *data++;
117 b = *data++;
118 *line++ = 0;
119 *line++ = r;
120 *line++ = g;
121 *line++ = b;
122 }
123 else
124 for (int x = 0; x < width; x++)
125 {
126 uint32_t v = *(uint32_t *)data; data += 4;
127 v = ecb_big_endian () ? ecb_rotr32 (v, 8) : ecb_rotl32 (v, 8);
128 *(uint32_t *)line = x; line += 4;
129 }
130
131 row += rowstride;
132 }
133
134 rxvt_img *img = new rxvt_img (s, XRenderFindStandardFormat (dpy, depth == 24 ? PictStandardRGB24 : PictStandardARGB32), 0, 0, width, height);
135 img->alloc ();
136
137 GC gc = XCreateGC (dpy, img->pm, 0, 0);
138 XPutImage (dpy, img->pm, gc, &xi, 0, 0, 0, 0, width, height);
139 XFreeGC (dpy, gc);
140
141 free (xi.data);
142
143 return img;
18} 144}
19 145
20rxvt_img * 146rxvt_img *
21rxvt_img::new_from_file (rxvt_screen *s, const char *filename) 147rxvt_img::new_from_file (rxvt_screen *s, const char *filename)
22{ 148{
24 GdkPixbuf *pb = gdk_pixbuf_new_from_file (filename, &err); 150 GdkPixbuf *pb = gdk_pixbuf_new_from_file (filename, &err);
25 151
26 if (!pb) 152 if (!pb)
27 rxvt_fatal ("rxvt_img::new_from_file: %s\n", err->message); 153 rxvt_fatal ("rxvt_img::new_from_file: %s\n", err->message);
28 154
29 rxvt_img *img = new rxvt_img ( 155 rxvt_img *img = new_from_pixbuf (s, pb);
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 156
36 img->render (pb, 0, 0, img->w, img->h, 0, 0); 157 g_object_unref (pb);
37 158
159 return img;
160}
161
162void
163rxvt_img::destroy ()
164{
165 if (--ref->cnt)
38 return img; 166 return;
167
168 if (pm && ref->ours)
169 XFreePixmap (s->display->dpy, pm);
170
171 delete ref;
39} 172}
40 173
41rxvt_img::~rxvt_img () 174rxvt_img::~rxvt_img ()
42{ 175{
43 if (!shared) 176 destroy ();
44 XFreePixmap (s->display->dpy, pm); 177}
178
179void
180rxvt_img::alloc ()
181{
182 pm = XCreatePixmap (s->display->dpy, s->display->root, w, h, format->depth);
183 ref = new pixref (w, h);
184}
185
186Picture
187rxvt_img::src_picture ()
188{
189 Display *dpy = s->display->dpy;
190
191 XRenderPictureAttributes pa;
192 pa.repeat = repeat;
193 Picture pic = XRenderCreatePicture (dpy, pm, format, CPRepeat, &pa);
194
195 return pic;
45} 196}
46 197
47void 198void
48rxvt_img::unshare () 199rxvt_img::unshare ()
49{ 200{
50 if (!shared) 201 if (ref->cnt == 1 && ref->ours)
51 return; 202 return;
52 203
53 rxvt_img *img = clone (); 204 //TODO: maybe should reify instead
205 Pixmap pm2 = XCreatePixmap (s->display->dpy, s->display->root, ref->w, ref->h, format->depth);
206 GC gc = XCreateGC (s->display->dpy, pm, 0, 0);
207 XCopyArea (s->display->dpy, pm, pm2, gc, 0, 0, ref->w, ref->h, 0, 0);
208 XFreeGC (s->display->dpy, gc);
54 209
55 ::swap (pm , img->pm); 210 destroy ();
56 ::swap (shared, img->shared);
57 211
58 delete img; 212 pm = pm2;
213 ref = new pixref (ref->w, ref->h);
59} 214}
60 215
61void 216void
62rxvt_img::fill (const rxvt_color &c) 217rxvt_img::fill (const rxvt_color &c)
63{ 218{
87 242
88 for (int i = 0; i < width; i++) 243 for (int i = 0; i < width; i++)
89 params[i+2] = XDoubleToFixed (kernel[i] / sum); 244 params[i+2] = XDoubleToFixed (kernel[i] / sum);
90} 245}
91 246
92void 247rxvt_img *
93rxvt_img::blur (int rh, int rv) 248rxvt_img::blur (int rh, int rv)
94{ 249{
95 if (!(s->display->flags & DISPLAY_HAS_RENDER_CONV)) 250 if (!(s->display->flags & DISPLAY_HAS_RENDER_CONV))
96 return; 251 return clone ();
97 252
98 Display *dpy = s->display->dpy; 253 Display *dpy = s->display->dpy;
99 int size = max (rh, rv) * 2 + 1; 254 int size = max (rh, rv) * 2 + 1;
100 double *kernel = (double *)malloc (size * sizeof (double)); 255 double *kernel = (double *)malloc (size * sizeof (double));
101 XFixed *params = (XFixed *)malloc ((size + 2) * sizeof (XFixed)); 256 XFixed *params = (XFixed *)malloc ((size + 2) * sizeof (XFixed));
257 rxvt_img *img = new rxvt_img (s, format, x, y, w, h, repeat);
258 img->alloc ();
259
260 Picture src = src_picture ();
102 261
103 XRenderPictureAttributes pa; 262 XRenderPictureAttributes pa;
104
105 pa.repeat = RepeatPad; 263 pa.repeat = RepeatPad;
106 Picture src = XRenderCreatePicture (dpy, pm, format, CPRepeat, &pa); 264 Picture dst = XRenderCreatePicture (dpy, img->pm, format, CPRepeat, &pa);
265
107 Pixmap tmp = XCreatePixmap (dpy, pm, w, h, format->depth); 266 Pixmap tmp_pm = XCreatePixmap (dpy, pm, w, h, format->depth);
108 Picture dst = XRenderCreatePicture (dpy, tmp, format, CPRepeat, &pa); 267 Picture tmp = XRenderCreatePicture (dpy, tmp_pm , format, CPRepeat, &pa);
109 XFreePixmap (dpy, tmp); 268 XFreePixmap (dpy, tmp_pm);
110 269
111 if (kernel && params) 270 if (kernel && params)
112 { 271 {
113 size = rh * 2 + 1; 272 size = rh * 2 + 1;
114 get_gaussian_kernel (rh, size, kernel, params); 273 get_gaussian_kernel (rh, size, kernel, params);
116 XRenderSetPictureFilter (dpy, src, FilterConvolution, params, size+2); 275 XRenderSetPictureFilter (dpy, src, FilterConvolution, params, size+2);
117 XRenderComposite (dpy, 276 XRenderComposite (dpy,
118 PictOpSrc, 277 PictOpSrc,
119 src, 278 src,
120 None, 279 None,
121 dst, 280 tmp,
122 0, 0, 281 0, 0,
123 0, 0, 282 0, 0,
124 0, 0, 283 0, 0,
125 w, h); 284 w, h);
126 285
127 ::swap (src, dst);
128
129 size = rv * 2 + 1; 286 size = rv * 2 + 1;
130 get_gaussian_kernel (rv, size, kernel, params); 287 get_gaussian_kernel (rv, size, kernel, params);
131 ::swap (params[0], params[1]); 288 ::swap (params[0], params[1]);
132 289
133 XRenderSetPictureFilter (dpy, src, FilterConvolution, params, size+2); 290 XRenderSetPictureFilter (dpy, src, FilterConvolution, params, size+2);
134 XRenderComposite (dpy, 291 XRenderComposite (dpy,
135 PictOpSrc, 292 PictOpSrc,
136 src, 293 tmp,
137 None, 294 None,
138 dst, 295 dst,
139 0, 0, 296 0, 0,
140 0, 0, 297 0, 0,
141 0, 0, 298 0, 0,
144 301
145 free (kernel); 302 free (kernel);
146 free (params); 303 free (params);
147 XRenderFreePicture (dpy, src); 304 XRenderFreePicture (dpy, src);
148 XRenderFreePicture (dpy, dst); 305 XRenderFreePicture (dpy, dst);
306 XRenderFreePicture (dpy, tmp);
307
308 return img;
149} 309}
150 310
151static Picture 311static Picture
152create_xrender_mask (Display *dpy, Drawable drawable, Bool argb) 312create_xrender_mask (Display *dpy, Drawable drawable, Bool argb)
153{ 313{
162 322
163 return mask; 323 return mask;
164} 324}
165 325
166void 326void
167rxvt_img::brightness (double r, double g, double b, double a) 327rxvt_img::brightness (unsigned short r, unsigned short g, unsigned short b, unsigned short a)
168{ 328{
169 Display *dpy = s->display->dpy; 329 Display *dpy = s->display->dpy;
170 Picture src = create_xrender_mask (dpy, pm, True); 330 Picture src = create_xrender_mask (dpy, pm, True);
171 Picture dst = XRenderCreatePicture (dpy, pm, format, 0, 0); 331 Picture dst = XRenderCreatePicture (dpy, pm, format, 0, 0);
172 332
173 XRenderColor mask_c; 333 XRenderColor mask_c;
174 mask_c.red = float_to_component (r); 334 mask_c.red = r;
175 mask_c.green = float_to_component (g); 335 mask_c.green = g;
176 mask_c.blue = float_to_component (b); 336 mask_c.blue = b;
177 mask_c.alpha = float_to_component (a); 337 mask_c.alpha = a;
178 XRenderFillRectangle (dpy, PictOpSrc, src, &mask_c, 0, 0, 1, 1); 338 XRenderFillRectangle (dpy, PictOpSrc, src, &mask_c, 0, 0, 1, 1);
179 339
180 XRenderComposite (dpy, PictOpAdd, src, None, dst, 0, 0, 0, 0, 0, 0, w, h); 340 XRenderComposite (dpy, PictOpAdd, src, None, dst, 0, 0, 0, 0, 0, 0, w, h);
341
342 XRenderFreePicture (dpy, src);
343 XRenderFreePicture (dpy, dst);
181} 344}
182 345
183void 346void
184rxvt_img::contrast (double r, double g, double b, double a) 347rxvt_img::contrast (unsigned short r, unsigned short g, unsigned short b, unsigned short a)
185{ 348{
186 if (!(s->display->flags & DISPLAY_HAS_RENDER_MUL)) 349 if (!(s->display->flags & DISPLAY_HAS_RENDER_MUL))
187 return; 350 return;
188 351
189 Display *dpy = s->display->dpy; 352 Display *dpy = s->display->dpy;
190 Picture src = create_xrender_mask (dpy, pm, True); 353 Picture src = create_xrender_mask (dpy, pm, True);
191 Picture dst = XRenderCreatePicture (dpy, pm, format, 0, 0); 354 Picture dst = XRenderCreatePicture (dpy, pm, format, 0, 0);
192 355
193 XRenderColor mask_c; 356 XRenderColor mask_c;
194 mask_c.red = float_to_component (r); 357 mask_c.red = r;
195 mask_c.green = float_to_component (g); 358 mask_c.green = g;
196 mask_c.blue = float_to_component (b); 359 mask_c.blue = b;
197 mask_c.alpha = float_to_component (a); 360 mask_c.alpha = a;
198 XRenderFillRectangle (dpy, PictOpSrc, src, &mask_c, 0, 0, 1, 1); 361 XRenderFillRectangle (dpy, PictOpSrc, src, &mask_c, 0, 0, 1, 1);
199 362
200 XRenderComposite (dpy, PictOpMultiply, src, None, dst, 0, 0, 0, 0, 0, 0, w, h); 363 XRenderComposite (dpy, PictOpMultiply, src, None, dst, 0, 0, 0, 0, 0, 0, w, h);
201}
202 364
203void 365 XRenderFreePicture (dpy, src);
204rxvt_img::render (GdkPixbuf *pixbuf, int src_x, int src_y, int width, int height, int dst_x, int dst_y) 366 XRenderFreePicture (dpy, dst);
205{
206 //TODO
207} 367}
208 368
209rxvt_img * 369rxvt_img *
210rxvt_img::clone () 370rxvt_img::clone ()
211{ 371{
212 GC gc = XCreateGC (s->display->dpy, pm, 0, 0); 372 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} 373}
218 374
219rxvt_img * 375static XRenderPictFormat *
220rxvt_img::transform (int new_width, int new_height, int repeat, double matrix[9]) 376find_alpha_format_for (Display *dpy, XRenderPictFormat *format)
221{ 377{
222 rxvt_img *img = new rxvt_img (s, format, new_width, new_height); 378 if (format->direct.alphaMask)
379 return format; // already has alpha
223 380
381 // try to find a suitable alpha format, one bit alpha is enough for our purposes
382 if (format->type == PictTypeDirect)
383 for (int n = 0; XRenderPictFormat *f = XRenderFindFormat (dpy, 0, 0, n); ++n)
384 if (f->direct.alphaMask
385 && f->type == PictTypeDirect
386 && ecb_popcount32 (f->direct.redMask ) >= ecb_popcount32 (format->direct.redMask )
387 && ecb_popcount32 (f->direct.greenMask) >= ecb_popcount32 (format->direct.greenMask)
388 && ecb_popcount32 (f->direct.blueMask ) >= ecb_popcount32 (format->direct.blueMask ))
389 return f;
390
391 // should be a very good fallback
392 return XRenderFindStandardFormat (dpy, PictStandardARGB32);
393}
394
395rxvt_img *
396rxvt_img::reify ()
397{
398 if (x == 0 && y == 0 && w == ref->w && h == ref->h)
399 return clone ();
400
224 Display *dpy = s->display->dpy; 401 Display *dpy = s->display->dpy;
225 XRenderPictureAttributes pa; 402
226 pa.repeat = repeat; 403 bool alpha = !format->direct.alphaMask
227 Picture src = XRenderCreatePicture (dpy, pm, format, CPRepeat, &pa); 404 && (x || y)
405 && repeat == RepeatNone;
406
407 rxvt_img *img = new rxvt_img (s, alpha ? find_alpha_format_for (dpy, format) : format, 0, 0, w, h, repeat);
408 img->alloc ();
409
410 Picture src = src_picture ();
228 Picture dst = XRenderCreatePicture (dpy, img->pm, img->format, 0, 0); 411 Picture dst = XRenderCreatePicture (dpy, img->pm, img->format, 0, 0);
412
413 if (alpha)
414 {
415 XRenderColor rc = { 0, 0, 0, 0 };
416 XRenderFillRectangle (dpy, PictOpSrc, dst, &rc, 0, 0, w, h);//TODO: split into four fillrectangles
417 XRenderComposite (dpy, PictOpSrc, src, None, dst, 0, 0, 0, 0, -x, -y, ref->w, ref->h);
418 }
419 else
420 XRenderComposite (dpy, PictOpSrc, src, None, dst, x, y, 0, 0, 0, 0, w, h);
421
422 XRenderFreePicture (dpy, src);
423 XRenderFreePicture (dpy, dst);
424
425 return img;
426}
427
428rxvt_img *
429rxvt_img::sub_rect (int x, int y, int width, int height)
430{
431 rxvt_img *img = clone ();
432
433 img->x += x;
434 img->y += y;
435
436 if (w != width || h != height)
437 {
438 img->w = width;
439 img->h = height;
440
441 rxvt_img *img2 = img->reify ();
442 delete img;
443 img = img2;
444 }
445
446 return img;
447}
448
449rxvt_img *
450rxvt_img::transform (int new_width, int new_height, double matrix[9])
451{
452 rxvt_img *img = new rxvt_img (s, format, 0, 0, new_width, new_height, repeat);
453 img->alloc ();
454
455 Display *dpy = s->display->dpy;
456 Picture src = src_picture ();
457 Picture dst = XRenderCreatePicture (dpy, img->pm, img->format, 0, 0);
229 458
230 XTransform xfrm; 459 XTransform xfrm;
231 460
232 for (int i = 0; i < 3; ++i) 461 for (int i = 0; i < 3; ++i)
233 for (int j = 0; j < 3; ++j) 462 for (int j = 0; j < 3; ++j)
234 xfrm.matrix [i][j] = XDoubleToFixed (matrix [i * 3 + j]); 463 xfrm.matrix [i][j] = XDoubleToFixed (matrix [i * 3 + j]);
235 464
465#if 0
466 xfrm.matrix [0][2] -= XDoubleToFixed (x);//TODO
467 xfrm.matrix [1][2] -= XDoubleToFixed (y);
468#endif
469
470 XRenderSetPictureFilter (dpy, src, "good", 0, 0);
236 XRenderSetPictureTransform (dpy, src, &xfrm); 471 XRenderSetPictureTransform (dpy, src, &xfrm);
237 XRenderComposite (dpy, PictOpSrc, src, None, dst, 0, 0, 0, 0, 0, 0, new_width, new_height); 472 XRenderComposite (dpy, PictOpSrc, src, None, dst, 0, 0, 0, 0, 0, 0, new_width, new_height);
238 473
239 XRenderFreePicture (dpy, src); 474 XRenderFreePicture (dpy, src);
240 XRenderFreePicture (dpy, dst); 475 XRenderFreePicture (dpy, dst);
243} 478}
244 479
245rxvt_img * 480rxvt_img *
246rxvt_img::scale (int new_width, int new_height) 481rxvt_img::scale (int new_width, int new_height)
247{ 482{
483 if (w == new_width && h == new_height)
484 return clone ();
485
248 double matrix[9] = { 486 double matrix[9] = {
249 new_width / (double)w, 0, 0, 487 w / (double)new_width, 0, 0,
250 0, new_height / (double)h, 0, 488 0, h / (double)new_height, 0,
251 0, 0, 1 489 0, 0, 1
252 }; 490 };
253 491
492 int old_repeat_mode = repeat;
493 repeat = RepeatPad; // not right, but xrender can't proeprly scale it seems
494
495 rxvt_img *img = transform (new_width, new_height, matrix);
496
497 repeat = old_repeat_mode;
498 img->repeat = repeat;
499
500 return img;
501}
502
503rxvt_img *
504rxvt_img::rotate (int new_width, int new_height, int x, int y, double phi)
505{
506 double s = sin (phi);
507 double c = cos (phi);
508
509 double matrix[9] = {
510 c, -s, -c * x + s * y + x,
511 s, c, -s * x - c * y + y,
512 0, 0, 1
513 };
514
254 return transform (new_width, new_height, RepeatNormal, matrix); 515 return transform (new_width, new_height, matrix);
255} 516}
256 517
257rxvt_img * 518rxvt_img *
258rxvt_img::convert_to (XRenderPictFormat *new_format) 519rxvt_img::convert_format (XRenderPictFormat *new_format, const rxvt_color &bg)
259{ 520{
521 if (new_format == format)
522 return clone ();
523
260 rxvt_img *img = new rxvt_img (s, new_format, w, h); 524 rxvt_img *img = new rxvt_img (s, new_format, x, y, w, h, repeat);
525 img->alloc ();
261 526
262 Display *dpy = s->display->dpy; 527 Display *dpy = s->display->dpy;
263 Picture src = XRenderCreatePicture (dpy, pm, format, 0, 0); 528 Picture src = src_picture ();
264 Picture dst = XRenderCreatePicture (dpy, img->pm, new_format, 0, 0); 529 Picture dst = XRenderCreatePicture (dpy, img->pm, new_format, 0, 0);
530 int op = PictOpSrc;
265 531
532 if (format->direct.alphaMask && !new_format->direct.alphaMask)
533 {
534 // does it have to be that complicated
535 rgba c;
536 bg.get (c);
537
538 XRenderColor rc = { c.r, c.g, c.b, 0xffff };
539 XRenderFillRectangle (dpy, PictOpSrc, dst, &rc, 0, 0, w, h);
540
541 op = PictOpOver;
542 }
543
266 XRenderComposite (dpy, PictOpSrc, src, None, dst, 0, 0, 0, 0, 0, 0, w, h); 544 XRenderComposite (dpy, op, src, None, dst, 0, 0, 0, 0, 0, 0, w, h);
267 545
268 XRenderFreePicture (dpy, src);
269 XRenderFreePicture (dpy, dst); 546 XRenderFreePicture (dpy, src);
547 XRenderFreePicture (dpy, dst);
270 548
549 return img;
550}
551
552rxvt_img *
553rxvt_img::blend (rxvt_img *img, double factor)
554{
555 rxvt_img *img2 = clone ();
556 Display *dpy = s->display->dpy;
557 Picture src = img->src_picture ();
558 Picture dst = XRenderCreatePicture (dpy, img2->pm, img2->format, 0, 0);
559 Picture mask = create_xrender_mask (dpy, img->pm, False);
560
561 XRenderColor mask_c;
562
563 mask_c.alpha = float_to_component (factor);
564 mask_c.red =
565 mask_c.green =
566 mask_c.blue = 0;
567 XRenderFillRectangle (dpy, PictOpSrc, mask, &mask_c, 0, 0, 1, 1);
568
569 XRenderComposite (dpy, PictOpOver, src, mask, dst, 0, 0, 0, 0, 0, 0, w, h);
570
571 XRenderFreePicture (dpy, src);
572 XRenderFreePicture (dpy, dst);
573 XRenderFreePicture (dpy, mask);
574
271 return img; 575 return img2;
272} 576}
273 577
274#endif 578#endif
275 579

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines