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.14 by root, Mon Jun 4 15:53:12 2012 UTC vs.
Revision 1.39 by root, Thu Jun 7 10:19:23 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 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);
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{
206 bool argb = format->id == PictStandardARGB32;
207
208 Display *dpy = s->display->dpy; 296 Display *dpy = s->display->dpy;
209 297
210 if (s->visual->c_class != TrueColor) 298 if (s->visual->c_class != TrueColor)
211 return false; 299 return false;
212 300
213 uint32_t red_mask, green_mask, blue_mask, alpha_mask; 301 uint32_t red_mask, green_mask, blue_mask, alpha_mask;
214 302
215 if (argb) 303 red_mask = (uint32_t)format->direct.redMask << format->direct.red;
216 { 304 green_mask = (uint32_t)format->direct.greenMask << format->direct.green;
217 red_mask = 0xff << 16; 305 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; 306 alpha_mask = (uint32_t)format->direct.alphaMask << format->direct.alpha;
228 }
229 307
230 int width_r = ecb_popcount32 (red_mask); 308 int width_r = ecb_popcount32 (red_mask);
231 int width_g = ecb_popcount32 (green_mask); 309 int width_g = ecb_popcount32 (green_mask);
232 int width_b = ecb_popcount32 (blue_mask); 310 int width_b = ecb_popcount32 (blue_mask);
233 int width_a = ecb_popcount32 (alpha_mask); 311 int width_a = ecb_popcount32 (alpha_mask);
241 int sh_a = ecb_ctz32 (alpha_mask); 319 int sh_a = ecb_ctz32 (alpha_mask);
242 320
243 if (width > 32767 || height > 32767) 321 if (width > 32767 || height > 32767)
244 return false; 322 return false;
245 323
246 XImage *ximage = XCreateImage (dpy, s->visual, argb ? 32 : format->depth, ZPixmap, 0, 0, 324 XImage *ximage = XCreateImage (dpy, s->visual, format->depth, ZPixmap, 0, 0,
247 width, height, 32, 0); 325 width, height, 32, 0);
248 if (!ximage) 326 if (!ximage)
249 return false; 327 return false;
250 328
251 if (height > INT_MAX / ximage->bytes_per_line 329 if (height > INT_MAX / ximage->bytes_per_line
261 339
262 int rowstride = gdk_pixbuf_get_rowstride (pixbuf); 340 int rowstride = gdk_pixbuf_get_rowstride (pixbuf);
263 int channels = gdk_pixbuf_get_n_channels (pixbuf); 341 int channels = gdk_pixbuf_get_n_channels (pixbuf);
264 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;
265 char *line = ximage->data; 343 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 >>= 8;
274 c.g >>= 8;
275 c.b >>= 8;
276 }
277 344
278 for (int y = 0; y < height; y++) 345 for (int y = 0; y < height; y++)
279 { 346 {
280 for (int x = 0; x < width; x++) 347 for (int x = 0; x < width; x++)
281 { 348 {
284 unsigned char r, g, b, a; 351 unsigned char r, g, b, a;
285 352
286 if (channels == 4) 353 if (channels == 4)
287 { 354 {
288 a = pixel[3]; 355 a = pixel[3];
289 r = (pixel[0] * a + c.r * (0xff - a)) / 0xff; 356 r = pixel[0] * a / 0xff;
290 g = (pixel[1] * a + c.g * (0xff - a)) / 0xff; 357 g = pixel[1] * a / 0xff;
291 b = (pixel[2] * a + c.b * (0xff - a)) / 0xff; 358 b = pixel[2] * a / 0xff;
292 } 359 }
293 else 360 else
294 { 361 {
295 a = 0xff; 362 a = 0xff;
296 r = pixel[0]; 363 r = pixel[0];
321} 388}
322 389
323rxvt_img * 390rxvt_img *
324rxvt_img::clone () 391rxvt_img::clone ()
325{ 392{
326 GC gc = XCreateGC (s->display->dpy, pm, 0, 0); 393 return new rxvt_img (*this);
327 Pixmap pm2 = XCreatePixmap (s->display->dpy, pm, w, h, format->depth);
328 XCopyArea (s->display->dpy, pm, pm2, gc, 0, 0, w, h, 0, 0);
329 XFreeGC (s->display->dpy, gc);
330 return new rxvt_img (s, format, w, h, pm2);
331} 394}
332 395
333rxvt_img * 396rxvt_img *
397rxvt_img::reify ()
398{
399 if (x == 0 && y == 0 && w == ref->w && h == ref->h)
400 return clone ();
401
402 rxvt_img *img = new rxvt_img (s, format, 0, 0, w, h);
403 img->alloc ();
404
405 Display *dpy = s->display->dpy;
406
407 Picture src = src_picture ();
408 Picture dst = XRenderCreatePicture (dpy, img->pm, img->format, 0, 0);
409
410 XRenderComposite (dpy, PictOpSrc, src, None, dst, x, y, 0, 0, 0, 0, w, h);
411
412 XRenderFreePicture (dpy, src);
413 XRenderFreePicture (dpy, dst);
414
415 return img;
416}
417
418rxvt_img *
419rxvt_img::sub_rect (int x, int y, int width, int height)
420{
421 rxvt_img *img = clone ();
422
423 img->x += x;
424 img->y += y;
425
426 if (w != width || h != height)
427 {
428 img->w = width;
429 img->h = height;
430
431 rxvt_img *img2 = img->reify ();
432 delete img;
433 img = img2;
434 }
435
436 return img;
437}
438
439rxvt_img *
334rxvt_img::transform (int new_width, int new_height, int repeat, double matrix[9]) 440rxvt_img::transform (int new_width, int new_height, double matrix[9])
335{ 441{
336 rxvt_img *img = new rxvt_img (s, format, new_width, new_height); 442 rxvt_img *img = new rxvt_img (s, format, 0, 0, new_width, new_height);
443 img->alloc ();
337 444
338 Display *dpy = s->display->dpy; 445 Display *dpy = s->display->dpy;
339 XRenderPictureAttributes pa; 446 Picture src = src_picture ();
340 pa.repeat = repeat;
341 Picture src = XRenderCreatePicture (dpy, pm, format, CPRepeat, &pa);
342 Picture dst = XRenderCreatePicture (dpy, img->pm, img->format, 0, 0); 447 Picture dst = XRenderCreatePicture (dpy, img->pm, img->format, 0, 0);
343 448
344 XTransform xfrm; 449 XTransform xfrm;
345 450
346 for (int i = 0; i < 3; ++i) 451 for (int i = 0; i < 3; ++i)
347 for (int j = 0; j < 3; ++j) 452 for (int j = 0; j < 3; ++j)
348 xfrm.matrix [i][j] = XDoubleToFixed (matrix [i * 3 + j]); 453 xfrm.matrix [i][j] = XDoubleToFixed (matrix [i * 3 + j]);
349 454
455 xfrm.matrix [0][2] += XDoubleToFixed (x);//TODO
456 xfrm.matrix [0][3] += XDoubleToFixed (y);
457
458 XRenderSetPictureFilter (dpy, src, "good", 0, 0);
350 XRenderSetPictureTransform (dpy, src, &xfrm); 459 XRenderSetPictureTransform (dpy, src, &xfrm);
351 XRenderComposite (dpy, PictOpSrc, src, None, dst, 0, 0, 0, 0, 0, 0, new_width, new_height); 460 XRenderComposite (dpy, PictOpSrc, src, None, dst, 0, 0, 0, 0, 0, 0, new_width, new_height);
352 461
353 XRenderFreePicture (dpy, src); 462 XRenderFreePicture (dpy, src);
354 XRenderFreePicture (dpy, dst); 463 XRenderFreePicture (dpy, dst);
358 467
359rxvt_img * 468rxvt_img *
360rxvt_img::scale (int new_width, int new_height) 469rxvt_img::scale (int new_width, int new_height)
361{ 470{
362 double matrix[9] = { 471 double matrix[9] = {
363 new_width / (double)w, 0, 0, 472 w / (double)new_width, 0, 0,
364 0, new_height / (double)h, 0, 473 0, h / (double)new_height, 0,
365 0, 0, 1 474 0, 0, 1
366 }; 475 };
367 476
368 return transform (new_width, new_height, RepeatNormal, matrix); 477 return transform (new_width, new_height, matrix);
369} 478}
370 479
371rxvt_img * 480rxvt_img *
481rxvt_img::rotate (int new_width, int new_height, int x, int y, double phi)
482{
483 double s = sin (phi);
484 double c = cos (phi);
485
486 double matrix[9] = {
487 c, -s, -c * x + s * y + x,
488 s, c, -s * x - c * y + y,
489 0, 0, 1
490 };
491
492 return transform (new_width, new_height, matrix);
493}
494
495rxvt_img *
372rxvt_img::convert_to (XRenderPictFormat *new_format) 496rxvt_img::convert_to (XRenderPictFormat *new_format, const rxvt_color &bg)
373{ 497{
498 if (new_format == format)
499 return clone ();
500
374 rxvt_img *img = new rxvt_img (s, new_format, w, h); 501 rxvt_img *img = new rxvt_img (s, new_format, 0, 0, w, h);
502 img->alloc ();
375 503
376 Display *dpy = s->display->dpy; 504 Display *dpy = s->display->dpy;
377 Picture src = XRenderCreatePicture (dpy, pm, format, 0, 0); 505 Picture src = src_picture ();
378 Picture dst = XRenderCreatePicture (dpy, img->pm, new_format, 0, 0); 506 Picture dst = XRenderCreatePicture (dpy, img->pm, new_format, 0, 0);
507 int op = PictOpSrc;
379 508
509 if (format->direct.alphaMask && !new_format->direct.alphaMask)
510 {
511 // does it have to be that complicated
512 rgba c;
513 bg.get (c);
514
515 XRenderColor rc = { c.r, c.g, c.b, 0xffff };
516 XRenderFillRectangle (dpy, PictOpSrc, dst, &rc, 0, 0, w, h);
517
518 op = PictOpOver;
519 }
520
380 XRenderComposite (dpy, PictOpSrc, src, None, dst, 0, 0, 0, 0, 0, 0, w, h); 521 XRenderComposite (dpy, op, src, None, dst, 0, 0, 0, 0, 0, 0, w, h);
381 522
382 XRenderFreePicture (dpy, src);
383 XRenderFreePicture (dpy, dst); 523 XRenderFreePicture (dpy, src);
524 XRenderFreePicture (dpy, dst);
384 525
526 return img;
527}
528
529rxvt_img *
530rxvt_img::blend (rxvt_img *img, double factor)
531{
532 rxvt_img *img2 = clone ();
533 Display *dpy = s->display->dpy;
534 Picture src = img->src_picture ();
535 Picture dst = XRenderCreatePicture (dpy, img2->pm, img2->format, 0, 0);
536 Picture mask = create_xrender_mask (dpy, img->pm, False);
537
538 XRenderColor mask_c;
539
540 mask_c.alpha = float_to_component (factor);
541 mask_c.red =
542 mask_c.green =
543 mask_c.blue = 0;
544 XRenderFillRectangle (dpy, PictOpSrc, mask, &mask_c, 0, 0, 1, 1);
545
546 XRenderComposite (dpy, PictOpOver, src, mask, dst, 0, 0, 0, 0, 0, 0, w, h);
547
548 XRenderFreePicture (dpy, src);
549 XRenderFreePicture (dpy, dst);
550 XRenderFreePicture (dpy, mask);
551
385 return img; 552 return img2;
386} 553}
387 554
388#endif 555#endif
389 556

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines