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

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines