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

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines