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.34 by root, Thu Jun 7 08:36:09 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{
18} 23}
24#endif
19 25
20rxvt_img * 26rxvt_img *
21rxvt_img::new_from_root (rxvt_screen *s) 27rxvt_img::new_from_root (rxvt_screen *s)
22{ 28{
23 Display *dpy = s->display->dpy; 29 Display *dpy = s->display->dpy;
37 return 0; 43 return 0;
38 44
39 rxvt_img *img = new rxvt_img ( 45 rxvt_img *img = new rxvt_img (
40 s, 46 s,
41 XRenderFindVisualFormat (dpy, DefaultVisual (dpy, s->display->screen)), 47 XRenderFindVisualFormat (dpy, DefaultVisual (dpy, s->display->screen)),
48 0,
49 0,
42 root_pm_w, 50 root_pm_w,
43 root_pm_h, 51 root_pm_h
44 root_pixmap
45 ); 52 );
46 53
47 img->shared = true; 54 img->pm = root_pixmap;
55 img->ref = new pixref (root_pm_w, root_pm_h);
56 img->ref->ours = false;
48 57
49 return img; 58 return img;
50} 59}
51 60
52rxvt_img * 61rxvt_img *
59 rxvt_fatal ("rxvt_img::new_from_file: %s\n", err->message); 68 rxvt_fatal ("rxvt_img::new_from_file: %s\n", err->message);
60 69
61 rxvt_img *img = new rxvt_img ( 70 rxvt_img *img = new rxvt_img (
62 s, 71 s,
63 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,
64 gdk_pixbuf_get_width (pb), 75 gdk_pixbuf_get_width (pb),
65 gdk_pixbuf_get_height (pb) 76 gdk_pixbuf_get_height (pb)
66 ); 77 );
67 78 img->alloc ();
68 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);
69 80
81 g_object_unref (pb);
82
83 return img;
84}
85
86void
87rxvt_img::destroy ()
88{
89 if (--ref->cnt)
70 return img; 90 return;
91
92 if (pm && ref->ours)
93 XFreePixmap (s->display->dpy, pm);
94
95 delete ref;
71} 96}
72 97
73rxvt_img::~rxvt_img () 98rxvt_img::~rxvt_img ()
74{ 99{
75 if (!shared) 100 destroy ();
76 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 XRectangle clip = { -x, -y, min (w, ref->w), min (h, ref->h) };
120 XRenderSetPictureClipRectangles (dpy, pic, 0, 0, &clip, 1);
121
122 return pic;
77} 123}
78 124
79void 125void
80rxvt_img::unshare () 126rxvt_img::unshare ()
81{ 127{
82 if (!shared) 128 if (ref->cnt == 1 && ref->ours)
83 return; 129 return;
84 130
85 rxvt_img *img = clone (); 131 //TODO: maybe should reify instead
132 Pixmap pm2 = XCreatePixmap (s->display->dpy, s->display->root, ref->w, ref->h, format->depth);
133 GC gc = XCreateGC (s->display->dpy, pm, 0, 0);
134 XCopyArea (s->display->dpy, pm, pm2, gc, 0, 0, ref->w, ref->h, 0, 0);
135 XFreeGC (s->display->dpy, gc);
86 136
87 ::swap (pm , img->pm); 137 destroy ();
88 ::swap (shared, img->shared);
89 138
90 delete img; 139 pm = pm2;
140 ref = new pixref (ref->w, ref->h);
91} 141}
92 142
93void 143void
94rxvt_img::fill (const rxvt_color &c) 144rxvt_img::fill (const rxvt_color &c)
95{ 145{
119 169
120 for (int i = 0; i < width; i++) 170 for (int i = 0; i < width; i++)
121 params[i+2] = XDoubleToFixed (kernel[i] / sum); 171 params[i+2] = XDoubleToFixed (kernel[i] / sum);
122} 172}
123 173
124void 174rxvt_img *
125rxvt_img::blur (int rh, int rv) 175rxvt_img::blur (int rh, int rv)
126{ 176{
127 if (!(s->display->flags & DISPLAY_HAS_RENDER_CONV)) 177 if (!(s->display->flags & DISPLAY_HAS_RENDER_CONV))
128 return; 178 return clone ();
129 179
130 Display *dpy = s->display->dpy; 180 Display *dpy = s->display->dpy;
131 int size = max (rh, rv) * 2 + 1; 181 int size = max (rh, rv) * 2 + 1;
132 double *kernel = (double *)malloc (size * sizeof (double)); 182 double *kernel = (double *)malloc (size * sizeof (double));
133 XFixed *params = (XFixed *)malloc ((size + 2) * sizeof (XFixed)); 183 XFixed *params = (XFixed *)malloc ((size + 2) * sizeof (XFixed));
184 rxvt_img *img = new rxvt_img (s, format, x, y, w, h);
185 img->alloc ();
186
187 Picture src = src_picture ();
134 188
135 XRenderPictureAttributes pa; 189 XRenderPictureAttributes pa;
136
137 pa.repeat = RepeatPad; 190 pa.repeat = RepeatPad;
138 Picture src = XRenderCreatePicture (dpy, pm , format, CPRepeat, &pa); 191 Picture dst = XRenderCreatePicture (dpy, img->pm, format, CPRepeat, &pa);
192
139 Pixmap tmp = XCreatePixmap (dpy, pm, w, h, format->depth); 193 Pixmap tmp_pm = XCreatePixmap (dpy, pm, w, h, format->depth);
140 Picture dst = XRenderCreatePicture (dpy, tmp, format, CPRepeat, &pa); 194 Picture tmp = XRenderCreatePicture (dpy, tmp_pm , format, CPRepeat, &pa);
141 XFreePixmap (dpy, tmp); 195 XFreePixmap (dpy, tmp_pm);
142 196
143 if (kernel && params) 197 if (kernel && params)
144 { 198 {
145 size = rh * 2 + 1; 199 size = rh * 2 + 1;
146 get_gaussian_kernel (rh, size, kernel, params); 200 get_gaussian_kernel (rh, size, kernel, params);
148 XRenderSetPictureFilter (dpy, src, FilterConvolution, params, size+2); 202 XRenderSetPictureFilter (dpy, src, FilterConvolution, params, size+2);
149 XRenderComposite (dpy, 203 XRenderComposite (dpy,
150 PictOpSrc, 204 PictOpSrc,
151 src, 205 src,
152 None, 206 None,
153 dst, 207 tmp,
154 0, 0, 208 0, 0,
155 0, 0, 209 0, 0,
156 0, 0, 210 0, 0,
157 w, h); 211 w, h);
158 212
159 ::swap (src, dst);
160
161 size = rv * 2 + 1; 213 size = rv * 2 + 1;
162 get_gaussian_kernel (rv, size, kernel, params); 214 get_gaussian_kernel (rv, size, kernel, params);
163 ::swap (params[0], params[1]); 215 ::swap (params[0], params[1]);
164 216
165 XRenderSetPictureFilter (dpy, src, FilterConvolution, params, size+2); 217 XRenderSetPictureFilter (dpy, src, FilterConvolution, params, size+2);
166 XRenderComposite (dpy, 218 XRenderComposite (dpy,
167 PictOpSrc, 219 PictOpSrc,
168 src, 220 tmp,
169 None, 221 None,
170 dst, 222 dst,
171 0, 0, 223 0, 0,
172 0, 0, 224 0, 0,
173 0, 0, 225 0, 0,
176 228
177 free (kernel); 229 free (kernel);
178 free (params); 230 free (params);
179 XRenderFreePicture (dpy, src); 231 XRenderFreePicture (dpy, src);
180 XRenderFreePicture (dpy, dst); 232 XRenderFreePicture (dpy, dst);
233 XRenderFreePicture (dpy, tmp);
234
235 return img;
181} 236}
182 237
183static Picture 238static Picture
184create_xrender_mask (Display *dpy, Drawable drawable, Bool argb) 239create_xrender_mask (Display *dpy, Drawable drawable, Bool argb)
185{ 240{
194 249
195 return mask; 250 return mask;
196} 251}
197 252
198void 253void
199rxvt_img::brightness (double r, double g, double b, double a) 254rxvt_img::brightness (unsigned short r, unsigned short g, unsigned short b, unsigned short a)
200{ 255{
201 Display *dpy = s->display->dpy; 256 Display *dpy = s->display->dpy;
202 Picture src = create_xrender_mask (dpy, pm, True); 257 Picture src = create_xrender_mask (dpy, pm, True);
203 Picture dst = XRenderCreatePicture (dpy, pm, format, 0, 0); 258 Picture dst = XRenderCreatePicture (dpy, pm, format, 0, 0);
204 259
205 XRenderColor mask_c; 260 XRenderColor mask_c;
206 mask_c.red = float_to_component (r); 261 mask_c.red = r;
207 mask_c.green = float_to_component (g); 262 mask_c.green = g;
208 mask_c.blue = float_to_component (b); 263 mask_c.blue = b;
209 mask_c.alpha = float_to_component (a); 264 mask_c.alpha = a;
210 XRenderFillRectangle (dpy, PictOpSrc, src, &mask_c, 0, 0, 1, 1); 265 XRenderFillRectangle (dpy, PictOpSrc, src, &mask_c, 0, 0, 1, 1);
211 266
212 XRenderComposite (dpy, PictOpAdd, src, None, dst, 0, 0, 0, 0, 0, 0, w, h); 267 XRenderComposite (dpy, PictOpAdd, src, None, dst, 0, 0, 0, 0, 0, 0, w, h);
268
269 XRenderFreePicture (dpy, src);
270 XRenderFreePicture (dpy, dst);
213} 271}
214 272
215void 273void
216rxvt_img::contrast (double r, double g, double b, double a) 274rxvt_img::contrast (unsigned short r, unsigned short g, unsigned short b, unsigned short a)
217{ 275{
218 if (!(s->display->flags & DISPLAY_HAS_RENDER_MUL)) 276 if (!(s->display->flags & DISPLAY_HAS_RENDER_MUL))
219 return; 277 return;
220 278
221 Display *dpy = s->display->dpy; 279 Display *dpy = s->display->dpy;
222 Picture src = create_xrender_mask (dpy, pm, True); 280 Picture src = create_xrender_mask (dpy, pm, True);
223 Picture dst = XRenderCreatePicture (dpy, pm, format, 0, 0); 281 Picture dst = XRenderCreatePicture (dpy, pm, format, 0, 0);
224 282
225 XRenderColor mask_c; 283 XRenderColor mask_c;
226 mask_c.red = float_to_component (r); 284 mask_c.red = r;
227 mask_c.green = float_to_component (g); 285 mask_c.green = g;
228 mask_c.blue = float_to_component (b); 286 mask_c.blue = b;
229 mask_c.alpha = float_to_component (a); 287 mask_c.alpha = a;
230 XRenderFillRectangle (dpy, PictOpSrc, src, &mask_c, 0, 0, 1, 1); 288 XRenderFillRectangle (dpy, PictOpSrc, src, &mask_c, 0, 0, 1, 1);
231 289
232 XRenderComposite (dpy, PictOpMultiply, src, None, dst, 0, 0, 0, 0, 0, 0, w, h); 290 XRenderComposite (dpy, PictOpMultiply, src, None, dst, 0, 0, 0, 0, 0, 0, w, h);
291
292 XRenderFreePicture (dpy, src);
293 XRenderFreePicture (dpy, dst);
233} 294}
234 295
235bool 296bool
236rxvt_img::render_pixbuf (GdkPixbuf *pixbuf, int src_x, int src_y, int width, int height, int dst_x, int dst_y) 297rxvt_img::render_pixbuf (GdkPixbuf *pixbuf, int src_x, int src_y, int width, int height, int dst_x, int dst_y)
237{ 298{
281 342
282 int rowstride = gdk_pixbuf_get_rowstride (pixbuf); 343 int rowstride = gdk_pixbuf_get_rowstride (pixbuf);
283 int channels = gdk_pixbuf_get_n_channels (pixbuf); 344 int channels = gdk_pixbuf_get_n_channels (pixbuf);
284 unsigned char *row = gdk_pixbuf_get_pixels (pixbuf) + src_y * rowstride + src_x * channels; 345 unsigned char *row = gdk_pixbuf_get_pixels (pixbuf) + src_y * rowstride + src_x * channels;
285 char *line = ximage->data; 346 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 347
299 for (int y = 0; y < height; y++) 348 for (int y = 0; y < height; y++)
300 { 349 {
301 for (int x = 0; x < width; x++) 350 for (int x = 0; x < width; x++)
302 { 351 {
305 unsigned char r, g, b, a; 354 unsigned char r, g, b, a;
306 355
307 if (channels == 4) 356 if (channels == 4)
308 { 357 {
309 a = pixel[3]; 358 a = pixel[3];
310 r = (pixel[0] * a + c.r * (0xff - a)) / 0xff; 359 r = pixel[0] * a / 0xff;
311 g = (pixel[1] * a + c.g * (0xff - a)) / 0xff; 360 g = pixel[1] * a / 0xff;
312 b = (pixel[2] * a + c.b * (0xff - a)) / 0xff; 361 b = pixel[2] * a / 0xff;
313 } 362 }
314 else 363 else
315 { 364 {
316 a = 0xff; 365 a = 0xff;
317 r = pixel[0]; 366 r = pixel[0];
342} 391}
343 392
344rxvt_img * 393rxvt_img *
345rxvt_img::clone () 394rxvt_img::clone ()
346{ 395{
396 return new rxvt_img (*this);
397}
398
399rxvt_img *
400rxvt_img::reify ()
401{
347 rxvt_img *img = new rxvt_img (s, format, w, h); 402 rxvt_img *img = new rxvt_img (s, format, 0, 0, w, h);
403 img->alloc ();
348 404
349 GC gc = XCreateGC (s->display->dpy, pm, 0, 0); 405 // 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); 406 // but that involves an rtt to find pixmap width.
351 XFreeGC (s->display->dpy, gc);
352 407
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
361 Display *dpy = s->display->dpy; 408 Display *dpy = s->display->dpy;
362 XRenderPictureAttributes pa; 409
363 pa.repeat = repeat; 410 Picture src = src_picture ();
364 Picture src = XRenderCreatePicture (dpy, pm, format, CPRepeat, &pa);
365 Picture dst = XRenderCreatePicture (dpy, img->pm, img->format, 0, 0); 411 Picture dst = XRenderCreatePicture (dpy, img->pm, img->format, 0, 0);
366 412
367 XRenderComposite (dpy, PictOpSrc, src, None, dst, x, y, 0, 0, 0, 0, width, height); 413 XRenderComposite (dpy, PictOpSrc, src, None, dst, x, y, 0, 0, 0, 0, w, h);
368 414
369 XRenderFreePicture (dpy, src);
370 XRenderFreePicture (dpy, dst); 415 XRenderFreePicture (dpy, src);
416 XRenderFreePicture (dpy, dst);
371 417
372 return img; 418 return img;
373} 419}
374 420
375rxvt_img * 421rxvt_img *
422rxvt_img::sub_rect (int x, int y, int width, int height)
423{
424 rxvt_img *img = clone ();
425
426 //TODO: width > w, must reify
427
428 img->x += x;
429 img->y += y;
430 img->w = width;
431 img->h = height;
432
433 return img;
434}
435
436rxvt_img *
376rxvt_img::transform (int new_width, int new_height, double matrix[9], int repeat) 437rxvt_img::transform (int new_width, int new_height, double matrix[9])
377{ 438{
378 rxvt_img *img = new rxvt_img (s, format, new_width, new_height); 439 rxvt_img *img = new rxvt_img (s, format, 0, 0, new_width, new_height);
440 img->alloc ();
379 441
380 Display *dpy = s->display->dpy; 442 Display *dpy = s->display->dpy;
381 XRenderPictureAttributes pa; 443 Picture src = src_picture ();
382 pa.repeat = repeat;
383 Picture src = XRenderCreatePicture (dpy, pm, format, CPRepeat, &pa);
384 Picture dst = XRenderCreatePicture (dpy, img->pm, img->format, 0, 0); 444 Picture dst = XRenderCreatePicture (dpy, img->pm, img->format, 0, 0);
385 445
386 XTransform xfrm; 446 XTransform xfrm;
387 447
388 for (int i = 0; i < 3; ++i) 448 for (int i = 0; i < 3; ++i)
389 for (int j = 0; j < 3; ++j) 449 for (int j = 0; j < 3; ++j)
390 xfrm.matrix [i][j] = XDoubleToFixed (matrix [i * 3 + j]); 450 xfrm.matrix [i][j] = XDoubleToFixed (matrix [i * 3 + j]);
451
452 xfrm.matrix [0][2] += XDoubleToFixed (x);//TODO
453 xfrm.matrix [0][3] += XDoubleToFixed (y);
391 454
392 XRenderSetPictureFilter (dpy, src, "good", 0, 0); 455 XRenderSetPictureFilter (dpy, src, "good", 0, 0);
393 XRenderSetPictureTransform (dpy, src, &xfrm); 456 XRenderSetPictureTransform (dpy, src, &xfrm);
394 XRenderComposite (dpy, PictOpSrc, src, None, dst, 0, 0, 0, 0, 0, 0, new_width, new_height); 457 XRenderComposite (dpy, PictOpSrc, src, None, dst, 0, 0, 0, 0, 0, 0, new_width, new_height);
395 458
410 473
411 return transform (new_width, new_height, matrix); 474 return transform (new_width, new_height, matrix);
412} 475}
413 476
414rxvt_img * 477rxvt_img *
415rxvt_img::rotate (int new_width, int new_height, int x, int y, double phi, int repeat) 478rxvt_img::rotate (int new_width, int new_height, int x, int y, double phi)
416{ 479{
417 double s = sin (phi); 480 double s = sin (phi);
418 double c = cos (phi); 481 double c = cos (phi);
419 482
420 double matrix[9] = { 483 double matrix[9] = {
421 c, -s, -c * x + s * y + x, 484 c, -s, -c * x + s * y + x,
422 s, c, -s * x - c * y + y, 485 s, c, -s * x - c * y + y,
423 0, 0, 1 486 0, 0, 1
424 }; 487 };
425 488
426 return transform (new_width, new_height, matrix, repeat); 489 return transform (new_width, new_height, matrix);
427} 490}
428 491
429rxvt_img * 492rxvt_img *
430rxvt_img::convert_to (XRenderPictFormat *new_format) 493rxvt_img::convert_to (XRenderPictFormat *new_format, const rxvt_color &bg)
431{ 494{
495 if (new_format == format)
496 return clone ();
497
432 rxvt_img *img = new rxvt_img (s, new_format, w, h); 498 rxvt_img *img = new rxvt_img (s, new_format, 0, 0, w, h);
499 img->alloc ();
433 500
434 Display *dpy = s->display->dpy; 501 Display *dpy = s->display->dpy;
435 Picture src = XRenderCreatePicture (dpy, pm, format, 0, 0); 502 Picture src = src_picture ();
436 Picture dst = XRenderCreatePicture (dpy, img->pm, new_format, 0, 0); 503 Picture dst = XRenderCreatePicture (dpy, img->pm, new_format, 0, 0);
504 int op = PictOpSrc;
437 505
506 if (format->direct.alphaMask && !new_format->direct.alphaMask)
507 {
508 // does it have to be that complicated
509 rgba c;
510 bg.get (c);
511
512 XRenderColor rc = { c.r, c.g, c.b, 0xffff };
513 XRenderFillRectangle (dpy, PictOpSrc, dst, &rc, 0, 0, w, h);
514
515 op = PictOpOver;
516 }
517
438 XRenderComposite (dpy, PictOpSrc, src, None, dst, 0, 0, 0, 0, 0, 0, w, h); 518 XRenderComposite (dpy, op, src, None, dst, 0, 0, 0, 0, 0, 0, w, h);
439 519
440 XRenderFreePicture (dpy, src);
441 XRenderFreePicture (dpy, dst); 520 XRenderFreePicture (dpy, src);
521 XRenderFreePicture (dpy, dst);
442 522
523 return img;
524}
525
526rxvt_img *
527rxvt_img::blend (rxvt_img *img, double factor)
528{
529 rxvt_img *img2 = clone ();
530 Display *dpy = s->display->dpy;
531 Picture src = src_picture ();
532 Picture dst = XRenderCreatePicture (dpy, img2->pm, img2->format, 0, 0);
533 Picture mask = create_xrender_mask (dpy, img->pm, False);
534
535 XRenderColor mask_c;
536
537 mask_c.alpha = float_to_component (factor);
538 mask_c.red =
539 mask_c.green =
540 mask_c.blue = 0;
541 XRenderFillRectangle (dpy, PictOpSrc, mask, &mask_c, 0, 0, 1, 1);
542
543 XRenderComposite (dpy, PictOpOver, src, mask, dst, 0, 0, 0, 0, 0, 0, w, h);
544
545 XRenderFreePicture (dpy, src);
546 XRenderFreePicture (dpy, dst);
547 XRenderFreePicture (dpy, mask);
548
443 return img; 549 return img2;
444} 550}
445 551
446#endif 552#endif
447 553

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines