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.16 by root, Mon Jun 4 16:12:55 2012 UTC vs.
Revision 1.30 by root, Wed Jun 6 22:01:44 2012 UTC

5#if HAVE_IMG 5#if HAVE_IMG
6 6
7#define float_to_component(d) ((d) * 65535.99) 7#define float_to_component(d) ((d) * 65535.99)
8 8
9rxvt_img::rxvt_img (rxvt_screen *screen, XRenderPictFormat *format, int width, int height) 9rxvt_img::rxvt_img (rxvt_screen *screen, XRenderPictFormat *format, int width, int height)
10: s(screen), w(width), h(height), format(format), shared(false) 10: s(screen), x(0), y(0), w(width), h(height), format(format), repeat(RepeatNormal), shared(false)
11{ 11{
12 pm = XCreatePixmap (s->display->dpy, s->display->root, w, h, format->depth); 12 pm = XCreatePixmap (s->display->dpy, s->display->root, w, h, format->depth);
13} 13}
14 14
15rxvt_img::rxvt_img (rxvt_screen *screen, XRenderPictFormat *format, int width, int height, Pixmap pixmap) 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) 16: s(screen), x(0), y(0), w(width), h(height), format(format), repeat(RepeatNormal), shared(false), pm(pixmap)
17{ 17{
18}
19
20rxvt_img *
21rxvt_img::new_from_root (rxvt_screen *s)
22{
23 Display *dpy = s->display->dpy;
24 unsigned int root_pm_w, root_pm_h;
25 Pixmap root_pixmap = s->display->get_pixmap_property (s->display->xa[XA_XROOTPMAP_ID]);
26 if (root_pixmap == None)
27 root_pixmap = s->display->get_pixmap_property (s->display->xa[XA_ESETROOT_PMAP_ID]);
28
29 if (root_pixmap == None)
30 return 0;
31
32 Window wdummy;
33 int idummy;
34 unsigned int udummy;
35
36 if (!XGetGeometry (dpy, root_pixmap, &wdummy, &idummy, &idummy, &root_pm_w, &root_pm_h, &udummy, &udummy))
37 return 0;
38
39 rxvt_img *img = new rxvt_img (
40 s,
41 XRenderFindVisualFormat (dpy, DefaultVisual (dpy, s->display->screen)),
42 root_pm_w,
43 root_pm_h,
44 root_pixmap
45 );
46
47 img->shared = true;
48
49 return img;
18} 50}
19 51
20rxvt_img * 52rxvt_img *
21rxvt_img::new_from_file (rxvt_screen *s, const char *filename) 53rxvt_img::new_from_file (rxvt_screen *s, const char *filename)
22{ 54{
33 gdk_pixbuf_get_height (pb) 65 gdk_pixbuf_get_height (pb)
34 ); 66 );
35 67
36 img->render_pixbuf (pb, 0, 0, img->w, img->h, 0, 0); 68 img->render_pixbuf (pb, 0, 0, img->w, img->h, 0, 0);
37 69
70 g_object_unref (pb);
71
38 return img; 72 return img;
39} 73}
40 74
41rxvt_img::~rxvt_img () 75rxvt_img::~rxvt_img ()
42{ 76{
87 121
88 for (int i = 0; i < width; i++) 122 for (int i = 0; i < width; i++)
89 params[i+2] = XDoubleToFixed (kernel[i] / sum); 123 params[i+2] = XDoubleToFixed (kernel[i] / sum);
90} 124}
91 125
92void 126rxvt_img *
93rxvt_img::blur (int rh, int rv) 127rxvt_img::blur (int rh, int rv)
94{ 128{
95 if (!(s->display->flags & DISPLAY_HAS_RENDER_CONV)) 129 if (!(s->display->flags & DISPLAY_HAS_RENDER_CONV))
96 return; 130 return clone ();
97 131
98 Display *dpy = s->display->dpy; 132 Display *dpy = s->display->dpy;
99 int size = max (rh, rv) * 2 + 1; 133 int size = max (rh, rv) * 2 + 1;
100 double *kernel = (double *)malloc (size * sizeof (double)); 134 double *kernel = (double *)malloc (size * sizeof (double));
101 XFixed *params = (XFixed *)malloc ((size + 2) * sizeof (XFixed)); 135 XFixed *params = (XFixed *)malloc ((size + 2) * sizeof (XFixed));
136 rxvt_img *img = new rxvt_img (s, format, w, h);
102 137
103 XRenderPictureAttributes pa; 138 XRenderPictureAttributes pa;
104 139
105 pa.repeat = RepeatPad; 140 pa.repeat = RepeatPad;
106 Picture src = XRenderCreatePicture (dpy, pm, format, CPRepeat, &pa); 141 Picture src = XRenderCreatePicture (dpy, pm , format, CPRepeat, &pa);
142 Picture dst = XRenderCreatePicture (dpy, img->pm, format, CPRepeat, &pa);
143
107 Pixmap tmp = XCreatePixmap (dpy, pm, w, h, format->depth); 144 Pixmap tmp_pm = XCreatePixmap (dpy, pm, w, h, format->depth);
108 Picture dst = XRenderCreatePicture (dpy, tmp, format, CPRepeat, &pa); 145 Picture tmp = XRenderCreatePicture (dpy, tmp_pm , format, CPRepeat, &pa);
109 XFreePixmap (dpy, tmp); 146 XFreePixmap (dpy, tmp_pm);
110 147
111 if (kernel && params) 148 if (kernel && params)
112 { 149 {
113 size = rh * 2 + 1; 150 size = rh * 2 + 1;
114 get_gaussian_kernel (rh, size, kernel, params); 151 get_gaussian_kernel (rh, size, kernel, params);
116 XRenderSetPictureFilter (dpy, src, FilterConvolution, params, size+2); 153 XRenderSetPictureFilter (dpy, src, FilterConvolution, params, size+2);
117 XRenderComposite (dpy, 154 XRenderComposite (dpy,
118 PictOpSrc, 155 PictOpSrc,
119 src, 156 src,
120 None, 157 None,
121 dst, 158 tmp,
122 0, 0, 159 0, 0,
123 0, 0, 160 0, 0,
124 0, 0, 161 0, 0,
125 w, h); 162 w, h);
126
127 ::swap (src, dst);
128 163
129 size = rv * 2 + 1; 164 size = rv * 2 + 1;
130 get_gaussian_kernel (rv, size, kernel, params); 165 get_gaussian_kernel (rv, size, kernel, params);
131 ::swap (params[0], params[1]); 166 ::swap (params[0], params[1]);
132 167
133 XRenderSetPictureFilter (dpy, src, FilterConvolution, params, size+2); 168 XRenderSetPictureFilter (dpy, src, FilterConvolution, params, size+2);
134 XRenderComposite (dpy, 169 XRenderComposite (dpy,
135 PictOpSrc, 170 PictOpSrc,
136 src, 171 tmp,
137 None, 172 None,
138 dst, 173 dst,
139 0, 0, 174 0, 0,
140 0, 0, 175 0, 0,
141 0, 0, 176 0, 0,
144 179
145 free (kernel); 180 free (kernel);
146 free (params); 181 free (params);
147 XRenderFreePicture (dpy, src); 182 XRenderFreePicture (dpy, src);
148 XRenderFreePicture (dpy, dst); 183 XRenderFreePicture (dpy, dst);
184 XRenderFreePicture (dpy, tmp);
185
186 return img;
149} 187}
150 188
151static Picture 189static Picture
152create_xrender_mask (Display *dpy, Drawable drawable, Bool argb) 190create_xrender_mask (Display *dpy, Drawable drawable, Bool argb)
153{ 191{
176 mask_c.blue = float_to_component (b); 214 mask_c.blue = float_to_component (b);
177 mask_c.alpha = float_to_component (a); 215 mask_c.alpha = float_to_component (a);
178 XRenderFillRectangle (dpy, PictOpSrc, src, &mask_c, 0, 0, 1, 1); 216 XRenderFillRectangle (dpy, PictOpSrc, src, &mask_c, 0, 0, 1, 1);
179 217
180 XRenderComposite (dpy, PictOpAdd, src, None, dst, 0, 0, 0, 0, 0, 0, w, h); 218 XRenderComposite (dpy, PictOpAdd, src, None, dst, 0, 0, 0, 0, 0, 0, w, h);
219
220 XRenderFreePicture (dpy, src);
221 XRenderFreePicture (dpy, dst);
181} 222}
182 223
183void 224void
184rxvt_img::contrast (double r, double g, double b, double a) 225rxvt_img::contrast (double r, double g, double b, double a)
185{ 226{
196 mask_c.blue = float_to_component (b); 237 mask_c.blue = float_to_component (b);
197 mask_c.alpha = float_to_component (a); 238 mask_c.alpha = float_to_component (a);
198 XRenderFillRectangle (dpy, PictOpSrc, src, &mask_c, 0, 0, 1, 1); 239 XRenderFillRectangle (dpy, PictOpSrc, src, &mask_c, 0, 0, 1, 1);
199 240
200 XRenderComposite (dpy, PictOpMultiply, src, None, dst, 0, 0, 0, 0, 0, 0, w, h); 241 XRenderComposite (dpy, PictOpMultiply, src, None, dst, 0, 0, 0, 0, 0, 0, w, h);
242
243 XRenderFreePicture (dpy, src);
244 XRenderFreePicture (dpy, dst);
201} 245}
202 246
203bool 247bool
204rxvt_img::render_pixbuf (GdkPixbuf *pixbuf, int src_x, int src_y, int width, int height, int dst_x, int dst_y) 248rxvt_img::render_pixbuf (GdkPixbuf *pixbuf, int src_x, int src_y, int width, int height, int dst_x, int dst_y)
205{ 249{
206 bool argb = format->id == PictStandardARGB32;
207
208 Display *dpy = s->display->dpy; 250 Display *dpy = s->display->dpy;
209 251
210 if (s->visual->c_class != TrueColor) 252 if (s->visual->c_class != TrueColor)
211 return false; 253 return false;
212 254
213 uint32_t red_mask, green_mask, blue_mask, alpha_mask; 255 uint32_t red_mask, green_mask, blue_mask, alpha_mask;
214 256
215 if (argb) 257 red_mask = (uint32_t)format->direct.redMask << format->direct.red;
216 { 258 green_mask = (uint32_t)format->direct.greenMask << format->direct.green;
217 red_mask = 0xff << 16; 259 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; 260 alpha_mask = (uint32_t)format->direct.alphaMask << format->direct.alpha;
228 }
229 261
230 int width_r = ecb_popcount32 (red_mask); 262 int width_r = ecb_popcount32 (red_mask);
231 int width_g = ecb_popcount32 (green_mask); 263 int width_g = ecb_popcount32 (green_mask);
232 int width_b = ecb_popcount32 (blue_mask); 264 int width_b = ecb_popcount32 (blue_mask);
233 int width_a = ecb_popcount32 (alpha_mask); 265 int width_a = ecb_popcount32 (alpha_mask);
241 int sh_a = ecb_ctz32 (alpha_mask); 273 int sh_a = ecb_ctz32 (alpha_mask);
242 274
243 if (width > 32767 || height > 32767) 275 if (width > 32767 || height > 32767)
244 return false; 276 return false;
245 277
246 XImage *ximage = XCreateImage (dpy, s->visual, argb ? 32 : format->depth, ZPixmap, 0, 0, 278 XImage *ximage = XCreateImage (dpy, s->visual, format->depth, ZPixmap, 0, 0,
247 width, height, 32, 0); 279 width, height, 32, 0);
248 if (!ximage) 280 if (!ximage)
249 return false; 281 return false;
250 282
251 if (height > INT_MAX / ximage->bytes_per_line 283 if (height > INT_MAX / ximage->bytes_per_line
261 293
262 int rowstride = gdk_pixbuf_get_rowstride (pixbuf); 294 int rowstride = gdk_pixbuf_get_rowstride (pixbuf);
263 int channels = gdk_pixbuf_get_n_channels (pixbuf); 295 int channels = gdk_pixbuf_get_n_channels (pixbuf);
264 unsigned char *row = gdk_pixbuf_get_pixels (pixbuf) + src_y * rowstride + src_x * channels; 296 unsigned char *row = gdk_pixbuf_get_pixels (pixbuf) + src_y * rowstride + src_x * channels;
265 char *line = ximage->data; 297 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 = 0xffff; c.g = 0xc0c0; c.b = 0xcbcb;//D
274 c.r >>= 8;
275 c.g >>= 8;
276 c.b >>= 8;
277 }
278 298
279 for (int y = 0; y < height; y++) 299 for (int y = 0; y < height; y++)
280 { 300 {
281 for (int x = 0; x < width; x++) 301 for (int x = 0; x < width; x++)
282 { 302 {
285 unsigned char r, g, b, a; 305 unsigned char r, g, b, a;
286 306
287 if (channels == 4) 307 if (channels == 4)
288 { 308 {
289 a = pixel[3]; 309 a = pixel[3];
290 r = (pixel[0] * a + c.r * (0xff - a)) / 0xff; 310 r = pixel[0] * a / 0xff;
291 g = (pixel[1] * a + c.g * (0xff - a)) / 0xff; 311 g = pixel[1] * a / 0xff;
292 b = (pixel[2] * a + c.b * (0xff - a)) / 0xff; 312 b = pixel[2] * a / 0xff;
293 } 313 }
294 else 314 else
295 { 315 {
296 a = 0xff; 316 a = 0xff;
297 r = pixel[0]; 317 r = pixel[0];
322} 342}
323 343
324rxvt_img * 344rxvt_img *
325rxvt_img::clone () 345rxvt_img::clone ()
326{ 346{
347 rxvt_img *img = new rxvt_img (s, format, w, h);
348
327 GC gc = XCreateGC (s->display->dpy, pm, 0, 0); 349 GC gc = XCreateGC (s->display->dpy, pm, 0, 0);
328 Pixmap pm2 = XCreatePixmap (s->display->dpy, pm, w, h, format->depth);
329 XCopyArea (s->display->dpy, pm, pm2, gc, 0, 0, w, h, 0, 0); 350 XCopyArea (s->display->dpy, pm, img->pm, gc, 0, 0, w, h, 0, 0);
330 XFreeGC (s->display->dpy, gc); 351 XFreeGC (s->display->dpy, gc);
331 return new rxvt_img (s, format, w, h, pm2);
332}
333 352
353 return img;
354}
355
334rxvt_img * 356rxvt_img *
335rxvt_img::transform (int new_width, int new_height, int repeat, double matrix[9]) 357rxvt_img::sub_rect (int x, int y, int width, int height)
336{ 358{
337 rxvt_img *img = new rxvt_img (s, format, new_width, new_height); 359 rxvt_img *img = new rxvt_img (s, format, width, height);
338 360
339 Display *dpy = s->display->dpy; 361 Display *dpy = s->display->dpy;
340 XRenderPictureAttributes pa; 362 XRenderPictureAttributes pa;
341 pa.repeat = repeat; 363 pa.repeat = repeat;
342 Picture src = XRenderCreatePicture (dpy, pm, format, CPRepeat, &pa); 364 Picture src = XRenderCreatePicture (dpy, pm, format, CPRepeat, &pa);
343 Picture dst = XRenderCreatePicture (dpy, img->pm, img->format, 0, 0); 365 Picture dst = XRenderCreatePicture (dpy, img->pm, img->format, 0, 0);
344 366
367 XRenderComposite (dpy, PictOpSrc, src, None, dst, x, y, 0, 0, 0, 0, width, height);
368
369 XRenderFreePicture (dpy, src);
370 XRenderFreePicture (dpy, dst);
371
372 return img;
373}
374
375rxvt_img *
376rxvt_img::transform (int new_width, int new_height, double matrix[9])
377{
378 rxvt_img *img = new rxvt_img (s, format, new_width, new_height);
379
380 Display *dpy = s->display->dpy;
381 XRenderPictureAttributes pa;
382 pa.repeat = repeat;
383 Picture src = XRenderCreatePicture (dpy, pm, format, CPRepeat, &pa);
384 Picture dst = XRenderCreatePicture (dpy, img->pm, img->format, 0, 0);
385
345 XTransform xfrm; 386 XTransform xfrm;
346 387
347 for (int i = 0; i < 3; ++i) 388 for (int i = 0; i < 3; ++i)
348 for (int j = 0; j < 3; ++j) 389 for (int j = 0; j < 3; ++j)
349 xfrm.matrix [i][j] = XDoubleToFixed (matrix [i * 3 + j]); 390 xfrm.matrix [i][j] = XDoubleToFixed (matrix [i * 3 + j]);
350 391
392 XRenderSetPictureFilter (dpy, src, "good", 0, 0);
351 XRenderSetPictureTransform (dpy, src, &xfrm); 393 XRenderSetPictureTransform (dpy, src, &xfrm);
352 XRenderComposite (dpy, PictOpSrc, src, None, dst, 0, 0, 0, 0, 0, 0, new_width, new_height); 394 XRenderComposite (dpy, PictOpSrc, src, None, dst, 0, 0, 0, 0, 0, 0, new_width, new_height);
353 395
354 XRenderFreePicture (dpy, src); 396 XRenderFreePicture (dpy, src);
355 XRenderFreePicture (dpy, dst); 397 XRenderFreePicture (dpy, dst);
364 w / (double)new_width, 0, 0, 406 w / (double)new_width, 0, 0,
365 0, h / (double)new_height, 0, 407 0, h / (double)new_height, 0,
366 0, 0, 1 408 0, 0, 1
367 }; 409 };
368 410
369 return transform (new_width, new_height, RepeatNormal, matrix); 411 return transform (new_width, new_height, matrix);
370} 412}
371 413
372rxvt_img * 414rxvt_img *
415rxvt_img::rotate (int new_width, int new_height, int x, int y, double phi)
416{
417 double s = sin (phi);
418 double c = cos (phi);
419
420 double matrix[9] = {
421 c, -s, -c * x + s * y + x,
422 s, c, -s * x - c * y + y,
423 0, 0, 1
424 };
425
426 return transform (new_width, new_height, matrix);
427}
428
429rxvt_img *
373rxvt_img::convert_to (XRenderPictFormat *new_format) 430rxvt_img::convert_to (XRenderPictFormat *new_format, const rxvt_color &bg)
374{ 431{
375 rxvt_img *img = new rxvt_img (s, new_format, w, h); 432 rxvt_img *img = new rxvt_img (s, new_format, w, h);
376 433
377 Display *dpy = s->display->dpy; 434 Display *dpy = s->display->dpy;
378 Picture src = XRenderCreatePicture (dpy, pm, format, 0, 0); 435 Picture src = XRenderCreatePicture (dpy, pm, format, 0, 0);
379 Picture dst = XRenderCreatePicture (dpy, img->pm, new_format, 0, 0); 436 Picture dst = XRenderCreatePicture (dpy, img->pm, new_format, 0, 0);
437 int op = PictOpSrc;
380 438
439 if (format->direct.alphaMask && !new_format->direct.alphaMask)
440 {
441 // does it have to be that complicated
442 rgba c;
443 bg.get (c);
444
445 XRenderColor rc = { c.r, c.g, c.b, 0xffff };
446 XRenderFillRectangle (dpy, PictOpSrc, dst, &rc, 0, 0, w, h);
447
448 op = PictOpOver;
449 }
450
381 XRenderComposite (dpy, PictOpSrc, src, None, dst, 0, 0, 0, 0, 0, 0, w, h); 451 XRenderComposite (dpy, op, src, None, dst, 0, 0, 0, 0, 0, 0, w, h);
382 452
383 XRenderFreePicture (dpy, src);
384 XRenderFreePicture (dpy, dst); 453 XRenderFreePicture (dpy, src);
454 XRenderFreePicture (dpy, dst);
385 455
456 return img;
457}
458
459rxvt_img *
460rxvt_img::blend (rxvt_img *img, double factor)
461{
462 rxvt_img *img2 = clone ();
463 Display *dpy = s->display->dpy;
464 Picture src = XRenderCreatePicture (dpy, img->pm, img->format, 0, 0);
465 Picture dst = XRenderCreatePicture (dpy, img2->pm, img2->format, 0, 0);
466 Picture mask = create_xrender_mask (dpy, img->pm, False);
467
468 XRenderColor mask_c;
469
470 mask_c.alpha = float_to_component (factor);
471 mask_c.red =
472 mask_c.green =
473 mask_c.blue = 0;
474 XRenderFillRectangle (dpy, PictOpSrc, mask, &mask_c, 0, 0, 1, 1);
475
476 XRenderComposite (dpy, PictOpOver, src, mask, dst, 0, 0, 0, 0, 0, 0, w, h);
477
478 XRenderFreePicture (dpy, src);
479 XRenderFreePicture (dpy, dst);
480 XRenderFreePicture (dpy, mask);
481
386 return img; 482 return img2;
387} 483}
388 484
389#endif 485#endif
390 486

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines