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.21 by sf-exg, Tue Jun 5 14:59:44 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{
18} 24}
25#endif
19 26
20rxvt_img * 27rxvt_img *
21rxvt_img::new_from_root (rxvt_screen *s) 28rxvt_img::new_from_root (rxvt_screen *s)
22{ 29{
23 Display *dpy = s->display->dpy; 30 Display *dpy = s->display->dpy;
37 return 0; 44 return 0;
38 45
39 rxvt_img *img = new rxvt_img ( 46 rxvt_img *img = new rxvt_img (
40 s, 47 s,
41 XRenderFindVisualFormat (dpy, DefaultVisual (dpy, s->display->screen)), 48 XRenderFindVisualFormat (dpy, DefaultVisual (dpy, s->display->screen)),
49 0,
50 0,
42 root_pm_w, 51 root_pm_w,
43 root_pm_h, 52 root_pm_h
44 root_pixmap
45 ); 53 );
46 54
47 img->shared = true; 55 img->pm = root_pixmap;
48 56
49 return img; 57 return img;
50} 58}
51 59
52rxvt_img * 60rxvt_img *
59 rxvt_fatal ("rxvt_img::new_from_file: %s\n", err->message); 67 rxvt_fatal ("rxvt_img::new_from_file: %s\n", err->message);
60 68
61 rxvt_img *img = new rxvt_img ( 69 rxvt_img *img = new rxvt_img (
62 s, 70 s,
63 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,
64 gdk_pixbuf_get_width (pb), 74 gdk_pixbuf_get_width (pb),
65 gdk_pixbuf_get_height (pb) 75 gdk_pixbuf_get_height (pb)
66 ); 76 );
67 77 img->alloc ();
68 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);
69 79
80 g_object_unref (pb);
81
82 return img;
83}
84
85void
86rxvt_img::destroy ()
87{
88 if (!refcnt || --*refcnt)
70 return img; 89 return;
90
91 if (pm)
92 XFreePixmap (s->display->dpy, pm);
93
94 delete refcnt;
71} 95}
72 96
73rxvt_img::~rxvt_img () 97rxvt_img::~rxvt_img ()
74{ 98{
75 if (!shared) 99 destroy ();
76 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);
77} 107}
78 108
79void 109void
80rxvt_img::unshare () 110rxvt_img::unshare ()
81{ 111{
82 if (!shared) 112 if (refcnt && *refcnt == 1)
83 return; 113 return;
84 114
85 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);
86 119
87 ::swap (pm , img->pm); 120 destroy ();
88 ::swap (shared, img->shared);
89 121
90 delete img; 122 pm = pm2;
123 refcnt = new int (1);
91} 124}
92 125
93void 126void
94rxvt_img::fill (const rxvt_color &c) 127rxvt_img::fill (const rxvt_color &c)
95{ 128{
119 152
120 for (int i = 0; i < width; i++) 153 for (int i = 0; i < width; i++)
121 params[i+2] = XDoubleToFixed (kernel[i] / sum); 154 params[i+2] = XDoubleToFixed (kernel[i] / sum);
122} 155}
123 156
124void 157rxvt_img *
125rxvt_img::blur (int rh, int rv) 158rxvt_img::blur (int rh, int rv)
126{ 159{
127 if (!(s->display->flags & DISPLAY_HAS_RENDER_CONV)) 160 if (!(s->display->flags & DISPLAY_HAS_RENDER_CONV))
128 return; 161 return clone ();
129 162
130 Display *dpy = s->display->dpy; 163 Display *dpy = s->display->dpy;
131 int size = max (rh, rv) * 2 + 1; 164 int size = max (rh, rv) * 2 + 1;
132 double *kernel = (double *)malloc (size * sizeof (double)); 165 double *kernel = (double *)malloc (size * sizeof (double));
133 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 ();
134 169
135 XRenderPictureAttributes pa; 170 XRenderPictureAttributes pa;
136 171
137 pa.repeat = RepeatPad; 172 pa.repeat = RepeatPad;
138 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
139 Pixmap tmp = XCreatePixmap (dpy, pm, w, h, format->depth); 176 Pixmap tmp_pm = XCreatePixmap (dpy, pm, w, h, format->depth);
140 Picture dst = XRenderCreatePicture (dpy, tmp, format, CPRepeat, &pa); 177 Picture tmp = XRenderCreatePicture (dpy, tmp_pm , format, CPRepeat, &pa);
141 XFreePixmap (dpy, tmp); 178 XFreePixmap (dpy, tmp_pm);
142 179
143 if (kernel && params) 180 if (kernel && params)
144 { 181 {
145 size = rh * 2 + 1; 182 size = rh * 2 + 1;
146 get_gaussian_kernel (rh, size, kernel, params); 183 get_gaussian_kernel (rh, size, kernel, params);
148 XRenderSetPictureFilter (dpy, src, FilterConvolution, params, size+2); 185 XRenderSetPictureFilter (dpy, src, FilterConvolution, params, size+2);
149 XRenderComposite (dpy, 186 XRenderComposite (dpy,
150 PictOpSrc, 187 PictOpSrc,
151 src, 188 src,
152 None, 189 None,
153 dst, 190 tmp,
154 0, 0, 191 0, 0,
155 0, 0, 192 0, 0,
156 0, 0, 193 0, 0,
157 w, h); 194 w, h);
158 195
159 ::swap (src, dst);
160
161 size = rv * 2 + 1; 196 size = rv * 2 + 1;
162 get_gaussian_kernel (rv, size, kernel, params); 197 get_gaussian_kernel (rv, size, kernel, params);
163 ::swap (params[0], params[1]); 198 ::swap (params[0], params[1]);
164 199
165 XRenderSetPictureFilter (dpy, src, FilterConvolution, params, size+2); 200 XRenderSetPictureFilter (dpy, src, FilterConvolution, params, size+2);
166 XRenderComposite (dpy, 201 XRenderComposite (dpy,
167 PictOpSrc, 202 PictOpSrc,
168 src, 203 tmp,
169 None, 204 None,
170 dst, 205 dst,
171 0, 0, 206 0, 0,
172 0, 0, 207 0, 0,
173 0, 0, 208 0, 0,
176 211
177 free (kernel); 212 free (kernel);
178 free (params); 213 free (params);
179 XRenderFreePicture (dpy, src); 214 XRenderFreePicture (dpy, src);
180 XRenderFreePicture (dpy, dst); 215 XRenderFreePicture (dpy, dst);
216 XRenderFreePicture (dpy, tmp);
217
218 return img;
181} 219}
182 220
183static Picture 221static Picture
184create_xrender_mask (Display *dpy, Drawable drawable, Bool argb) 222create_xrender_mask (Display *dpy, Drawable drawable, Bool argb)
185{ 223{
194 232
195 return mask; 233 return mask;
196} 234}
197 235
198void 236void
199rxvt_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)
200{ 238{
201 Display *dpy = s->display->dpy; 239 Display *dpy = s->display->dpy;
202 Picture src = create_xrender_mask (dpy, pm, True); 240 Picture src = create_xrender_mask (dpy, pm, True);
203 Picture dst = XRenderCreatePicture (dpy, pm, format, 0, 0); 241 Picture dst = XRenderCreatePicture (dpy, pm, format, 0, 0);
204 242
205 XRenderColor mask_c; 243 XRenderColor mask_c;
206 mask_c.red = float_to_component (r); 244 mask_c.red = r;
207 mask_c.green = float_to_component (g); 245 mask_c.green = g;
208 mask_c.blue = float_to_component (b); 246 mask_c.blue = b;
209 mask_c.alpha = float_to_component (a); 247 mask_c.alpha = a;
210 XRenderFillRectangle (dpy, PictOpSrc, src, &mask_c, 0, 0, 1, 1); 248 XRenderFillRectangle (dpy, PictOpSrc, src, &mask_c, 0, 0, 1, 1);
211 249
212 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);
213} 254}
214 255
215void 256void
216rxvt_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)
217{ 258{
218 if (!(s->display->flags & DISPLAY_HAS_RENDER_MUL)) 259 if (!(s->display->flags & DISPLAY_HAS_RENDER_MUL))
219 return; 260 return;
220 261
221 Display *dpy = s->display->dpy; 262 Display *dpy = s->display->dpy;
222 Picture src = create_xrender_mask (dpy, pm, True); 263 Picture src = create_xrender_mask (dpy, pm, True);
223 Picture dst = XRenderCreatePicture (dpy, pm, format, 0, 0); 264 Picture dst = XRenderCreatePicture (dpy, pm, format, 0, 0);
224 265
225 XRenderColor mask_c; 266 XRenderColor mask_c;
226 mask_c.red = float_to_component (r); 267 mask_c.red = r;
227 mask_c.green = float_to_component (g); 268 mask_c.green = g;
228 mask_c.blue = float_to_component (b); 269 mask_c.blue = b;
229 mask_c.alpha = float_to_component (a); 270 mask_c.alpha = a;
230 XRenderFillRectangle (dpy, PictOpSrc, src, &mask_c, 0, 0, 1, 1); 271 XRenderFillRectangle (dpy, PictOpSrc, src, &mask_c, 0, 0, 1, 1);
231 272
232 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);
233} 277}
234 278
235bool 279bool
236rxvt_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)
237{ 281{
281 325
282 int rowstride = gdk_pixbuf_get_rowstride (pixbuf); 326 int rowstride = gdk_pixbuf_get_rowstride (pixbuf);
283 int channels = gdk_pixbuf_get_n_channels (pixbuf); 327 int channels = gdk_pixbuf_get_n_channels (pixbuf);
284 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;
285 char *line = ximage->data; 329 char *line = ximage->data;
286
287 rgba c (0, 0, 0);
288
289 if (channels == 4 && alpha_mask == 0)
290 {
291 //pix_colors[Color_bg].get (c);
292 //TODO
293 c.r = 0xffff; c.g = 0xc0c0; c.b = 0xcbcb;//D
294 c.r >>= 8;
295 c.g >>= 8;
296 c.b >>= 8;
297 }
298 330
299 for (int y = 0; y < height; y++) 331 for (int y = 0; y < height; y++)
300 { 332 {
301 for (int x = 0; x < width; x++) 333 for (int x = 0; x < width; x++)
302 { 334 {
305 unsigned char r, g, b, a; 337 unsigned char r, g, b, a;
306 338
307 if (channels == 4) 339 if (channels == 4)
308 { 340 {
309 a = pixel[3]; 341 a = pixel[3];
310 r = (pixel[0] * a + c.r * (0xff - a)) / 0xff; 342 r = pixel[0] * a / 0xff;
311 g = (pixel[1] * a + c.g * (0xff - a)) / 0xff; 343 g = pixel[1] * a / 0xff;
312 b = (pixel[2] * a + c.b * (0xff - a)) / 0xff; 344 b = pixel[2] * a / 0xff;
313 } 345 }
314 else 346 else
315 { 347 {
316 a = 0xff; 348 a = 0xff;
317 r = pixel[0]; 349 r = pixel[0];
342} 374}
343 375
344rxvt_img * 376rxvt_img *
345rxvt_img::clone () 377rxvt_img::clone ()
346{ 378{
379 return new rxvt_img (*this);
380}
381
382rxvt_img *
383rxvt_img::reify ()
384{
347 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 ();
348 387
349 GC gc = XCreateGC (s->display->dpy, pm, 0, 0); 388 // todo, if x==0 and y==0 and w==real width we could clone
350 XCopyArea (s->display->dpy, pm, img->pm, gc, 0, 0, w, h, 0, 0); 389 // but that involves an rtt to find pixmap width.
351 XFreeGC (s->display->dpy, gc);
352
353 return img;
354}
355
356rxvt_img *
357rxvt_img::sub_rect (int x, int y, int width, int height, int repeat)
358{
359 rxvt_img *img = new rxvt_img (s, format, width, height);
360 390
361 Display *dpy = s->display->dpy; 391 Display *dpy = s->display->dpy;
362 XRenderPictureAttributes pa; 392 XRenderPictureAttributes pa;
363 pa.repeat = repeat; 393 pa.repeat = repeat;
364 Picture src = XRenderCreatePicture (dpy, pm, format, CPRepeat, &pa); 394 Picture src = XRenderCreatePicture (dpy, pm, format, CPRepeat, &pa);
365 Picture dst = XRenderCreatePicture (dpy, img->pm, img->format, 0, 0); 395 Picture dst = XRenderCreatePicture (dpy, img->pm, img->format, 0, 0);
366 396
367 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);
368 398
369 XRenderFreePicture (dpy, src);
370 XRenderFreePicture (dpy, dst); 399 XRenderFreePicture (dpy, src);
400 XRenderFreePicture (dpy, dst);
371 401
372 return img; 402 return img;
373} 403}
374 404
375rxvt_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 *
376rxvt_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])
377{ 420{
378 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 ();
379 423
380 Display *dpy = s->display->dpy; 424 Display *dpy = s->display->dpy;
381 XRenderPictureAttributes pa; 425 XRenderPictureAttributes pa;
382 pa.repeat = repeat; 426 pa.repeat = repeat;
383 Picture src = XRenderCreatePicture (dpy, pm, format, CPRepeat, &pa); 427 Picture src = XRenderCreatePicture (dpy, pm, format, CPRepeat, &pa);
386 XTransform xfrm; 430 XTransform xfrm;
387 431
388 for (int i = 0; i < 3; ++i) 432 for (int i = 0; i < 3; ++i)
389 for (int j = 0; j < 3; ++j) 433 for (int j = 0; j < 3; ++j)
390 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);
391 438
392 XRenderSetPictureFilter (dpy, src, "good", 0, 0); 439 XRenderSetPictureFilter (dpy, src, "good", 0, 0);
393 XRenderSetPictureTransform (dpy, src, &xfrm); 440 XRenderSetPictureTransform (dpy, src, &xfrm);
394 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);
395 442
410 457
411 return transform (new_width, new_height, matrix); 458 return transform (new_width, new_height, matrix);
412} 459}
413 460
414rxvt_img * 461rxvt_img *
415rxvt_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)
416{ 463{
417 double s = sin (phi); 464 double s = sin (phi);
418 double c = cos (phi); 465 double c = cos (phi);
419 466
420 double matrix[9] = { 467 double matrix[9] = {
421 c, -s, -c * x + s * y + x, 468 c, -s, -c * x + s * y + x,
422 s, c, -s * x - c * y + y, 469 s, c, -s * x - c * y + y,
423 0, 0, 1 470 0, 0, 1
424 }; 471 };
425 472
426 return transform (new_width, new_height, matrix, repeat); 473 return transform (new_width, new_height, matrix);
427} 474}
428 475
429rxvt_img * 476rxvt_img *
430rxvt_img::convert_to (XRenderPictFormat *new_format) 477rxvt_img::convert_to (XRenderPictFormat *new_format, const rxvt_color &bg)
431{ 478{
479 if (new_format == format)
480 return clone ();
481
432 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 ();
433 484
434 Display *dpy = s->display->dpy; 485 Display *dpy = s->display->dpy;
435 Picture src = XRenderCreatePicture (dpy, pm, format, 0, 0); 486 Picture src = XRenderCreatePicture (dpy, pm, format, 0, 0);
436 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;
437 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
438 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);
439 503
440 XRenderFreePicture (dpy, src);
441 XRenderFreePicture (dpy, dst); 504 XRenderFreePicture (dpy, src);
505 XRenderFreePicture (dpy, dst);
442 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
443 return img; 533 return img2;
444} 534}
445 535
446#endif 536#endif
447 537

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines