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.20 by root, Tue Jun 5 14:07:47 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{
249 325
250 int rowstride = gdk_pixbuf_get_rowstride (pixbuf); 326 int rowstride = gdk_pixbuf_get_rowstride (pixbuf);
251 int channels = gdk_pixbuf_get_n_channels (pixbuf); 327 int channels = gdk_pixbuf_get_n_channels (pixbuf);
252 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;
253 char *line = ximage->data; 329 char *line = ximage->data;
254
255 rgba c (0, 0, 0);
256
257 if (channels == 4 && alpha_mask == 0)
258 {
259 //pix_colors[Color_bg].get (c);
260 //TODO
261 c.r = 0xffff; c.g = 0xc0c0; c.b = 0xcbcb;//D
262 c.r >>= 8;
263 c.g >>= 8;
264 c.b >>= 8;
265 }
266 330
267 for (int y = 0; y < height; y++) 331 for (int y = 0; y < height; y++)
268 { 332 {
269 for (int x = 0; x < width; x++) 333 for (int x = 0; x < width; x++)
270 { 334 {
273 unsigned char r, g, b, a; 337 unsigned char r, g, b, a;
274 338
275 if (channels == 4) 339 if (channels == 4)
276 { 340 {
277 a = pixel[3]; 341 a = pixel[3];
278 r = (pixel[0] * a + c.r * (0xff - a)) / 0xff; 342 r = pixel[0] * a / 0xff;
279 g = (pixel[1] * a + c.g * (0xff - a)) / 0xff; 343 g = pixel[1] * a / 0xff;
280 b = (pixel[2] * a + c.b * (0xff - a)) / 0xff; 344 b = pixel[2] * a / 0xff;
281 } 345 }
282 else 346 else
283 { 347 {
284 a = 0xff; 348 a = 0xff;
285 r = pixel[0]; 349 r = pixel[0];
310} 374}
311 375
312rxvt_img * 376rxvt_img *
313rxvt_img::clone () 377rxvt_img::clone ()
314{ 378{
379 return new rxvt_img (*this);
380}
381
382rxvt_img *
383rxvt_img::reify ()
384{
315 rxvt_img *img = new rxvt_img (s, format, w, h); 385 rxvt_img *img = new rxvt_img (s, format, 0, 0, w, h);
386 img->alloc ();
316 387
317 GC gc = XCreateGC (s->display->dpy, pm, 0, 0); 388 // todo, if x==0 and y==0 and w==real width we could clone
318 XCopyArea (s->display->dpy, pm, img->pm, gc, 0, 0, w, h, 0, 0); 389 // but that involves an rtt to find pixmap width.
319 XFreeGC (s->display->dpy, gc);
320
321 return img;
322}
323
324rxvt_img *
325rxvt_img::sub_rect (int x, int y, int width, int height, int repeat)
326{
327 rxvt_img *img = new rxvt_img (s, format, width, height);
328 390
329 Display *dpy = s->display->dpy; 391 Display *dpy = s->display->dpy;
330 XRenderPictureAttributes pa; 392 XRenderPictureAttributes pa;
331 pa.repeat = repeat; 393 pa.repeat = repeat;
332 Picture src = XRenderCreatePicture (dpy, pm, format, CPRepeat, &pa); 394 Picture src = XRenderCreatePicture (dpy, pm, format, CPRepeat, &pa);
333 Picture dst = XRenderCreatePicture (dpy, img->pm, img->format, 0, 0); 395 Picture dst = XRenderCreatePicture (dpy, img->pm, img->format, 0, 0);
334 396
335 XRenderComposite (dpy, PictOpSrc, src, None, dst, x, y, 0, 0, 0, 0, width, height); 397 XRenderComposite (dpy, PictOpSrc, src, None, dst, x, y, 0, 0, 0, 0, w, h);
336 398
337 XRenderFreePicture (dpy, src);
338 XRenderFreePicture (dpy, dst); 399 XRenderFreePicture (dpy, src);
400 XRenderFreePicture (dpy, dst);
339 401
340 return img; 402 return img;
341} 403}
342 404
343rxvt_img * 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 *
344rxvt_img::transform (int new_width, int new_height, double matrix[9], int repeat) 419rxvt_img::transform (int new_width, int new_height, double matrix[9])
345{ 420{
346 rxvt_img *img = new rxvt_img (s, format, new_width, new_height); 421 rxvt_img *img = new rxvt_img (s, format, 0, 0, new_width, new_height);
422 img->alloc ();
347 423
348 Display *dpy = s->display->dpy; 424 Display *dpy = s->display->dpy;
349 XRenderPictureAttributes pa; 425 XRenderPictureAttributes pa;
350 pa.repeat = repeat; 426 pa.repeat = repeat;
351 Picture src = XRenderCreatePicture (dpy, pm, format, CPRepeat, &pa); 427 Picture src = XRenderCreatePicture (dpy, pm, format, CPRepeat, &pa);
354 XTransform xfrm; 430 XTransform xfrm;
355 431
356 for (int i = 0; i < 3; ++i) 432 for (int i = 0; i < 3; ++i)
357 for (int j = 0; j < 3; ++j) 433 for (int j = 0; j < 3; ++j)
358 xfrm.matrix [i][j] = XDoubleToFixed (matrix [i * 3 + j]); 434 xfrm.matrix [i][j] = XDoubleToFixed (matrix [i * 3 + j]);
435
436 xfrm.matrix [0][2] += XDoubleToFixed (x);//TODO
437 xfrm.matrix [0][3] += XDoubleToFixed (y);
359 438
360 XRenderSetPictureFilter (dpy, src, "good", 0, 0); 439 XRenderSetPictureFilter (dpy, src, "good", 0, 0);
361 XRenderSetPictureTransform (dpy, src, &xfrm); 440 XRenderSetPictureTransform (dpy, src, &xfrm);
362 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);
363 442
378 457
379 return transform (new_width, new_height, matrix); 458 return transform (new_width, new_height, matrix);
380} 459}
381 460
382rxvt_img * 461rxvt_img *
383rxvt_img::rotate (int new_width, int new_height, int x, int y, double phi, int repeat) 462rxvt_img::rotate (int new_width, int new_height, int x, int y, double phi)
384{ 463{
385 double s = sin (phi); 464 double s = sin (phi);
386 double c = cos (phi); 465 double c = cos (phi);
387 466
388 double matrix[9] = { 467 double matrix[9] = {
389 c, -s, -c * x + s * y + x, 468 c, -s, -c * x + s * y + x,
390 s, c, -s * x - c * y + y, 469 s, c, -s * x - c * y + y,
391 0, 0, 1 470 0, 0, 1
392 }; 471 };
393 472
394 return transform (new_width, new_height, matrix, repeat); 473 return transform (new_width, new_height, matrix);
395} 474}
396 475
397rxvt_img * 476rxvt_img *
398rxvt_img::convert_to (XRenderPictFormat *new_format) 477rxvt_img::convert_to (XRenderPictFormat *new_format, const rxvt_color &bg)
399{ 478{
479 if (new_format == format)
480 return clone ();
481
400 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 ();
401 484
402 Display *dpy = s->display->dpy; 485 Display *dpy = s->display->dpy;
403 Picture src = XRenderCreatePicture (dpy, pm, format, 0, 0); 486 Picture src = XRenderCreatePicture (dpy, pm, format, 0, 0);
404 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;
405 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
406 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);
407 503
408 XRenderFreePicture (dpy, src);
409 XRenderFreePicture (dpy, dst); 504 XRenderFreePicture (dpy, src);
505 XRenderFreePicture (dpy, dst);
410 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
411 return img; 533 return img2;
412} 534}
413 535
414#endif 536#endif
415 537

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines