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

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines