ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/rxvt-unicode/src/background.C
(Generate patch)

Comparing rxvt-unicode/src/background.C (file contents):
Revision 1.206 by sf-exg, Thu Apr 12 10:22:50 2012 UTC vs.
Revision 1.212 by sf-exg, Sun May 13 15:50:18 2012 UTC

3 *----------------------------------------------------------------------* 3 *----------------------------------------------------------------------*
4 * 4 *
5 * All portions of code are copyright by their respective author/s. 5 * All portions of code are copyright by their respective author/s.
6 * Copyright (c) 2005-2008 Marc Lehmann <schmorp@schmorp.de> 6 * Copyright (c) 2005-2008 Marc Lehmann <schmorp@schmorp.de>
7 * Copyright (c) 2007 Sasha Vasko <sasha@aftercode.net> 7 * Copyright (c) 2007 Sasha Vasko <sasha@aftercode.net>
8 * Copyright (c) 2010 Emanuele Giaquinta <e.giaquinta@glauco.it> 8 * Copyright (c) 2010-2012 Emanuele Giaquinta <e.giaquinta@glauco.it>
9 * 9 *
10 * This program is free software; you can redistribute it and/or modify 10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by 11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or 12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version. 13 * (at your option) any later version.
346rxvt_term::pixbuf_to_pixmap (GdkPixbuf *pixbuf, Pixmap pixmap, GC gc, 346rxvt_term::pixbuf_to_pixmap (GdkPixbuf *pixbuf, Pixmap pixmap, GC gc,
347 int src_x, int src_y, int dst_x, int dst_y, 347 int src_x, int src_y, int dst_x, int dst_y,
348 unsigned int width, unsigned int height) 348 unsigned int width, unsigned int height)
349{ 349{
350 XImage *ximage; 350 XImage *ximage;
351 char *data, *line; 351 char *line;
352 int bytes_per_pixel;
353 int width_r, width_g, width_b; 352 int width_r, width_g, width_b, width_a;
354 int sh_r, sh_g, sh_b; 353 int sh_r, sh_g, sh_b, sh_a;
354 uint32_t alpha_mask;
355 int rowstride; 355 int rowstride;
356 int channels; 356 int channels;
357 unsigned char *row; 357 unsigned char *row;
358 358
359 if (visual->c_class != TrueColor) 359 if (visual->c_class != TrueColor)
360 return false; 360 return false;
361 361
362 if (depth == 24 || depth == 32) 362#if XRENDER
363 bytes_per_pixel = 4; 363 XRenderPictFormat *format = XRenderFindVisualFormat (dpy, visual);
364 else if (depth == 15 || depth == 16) 364 if (format)
365 bytes_per_pixel = 2; 365 alpha_mask = (uint32_t)format->direct.alphaMask << format->direct.alpha;
366 else 366 else
367 return false; 367#endif
368 alpha_mask = 0;
368 369
369 width_r = ecb_popcount32 (visual->red_mask); 370 width_r = ecb_popcount32 (visual->red_mask);
370 width_g = ecb_popcount32 (visual->green_mask); 371 width_g = ecb_popcount32 (visual->green_mask);
371 width_b = ecb_popcount32 (visual->blue_mask); 372 width_b = ecb_popcount32 (visual->blue_mask);
373 width_a = ecb_popcount32 (alpha_mask);
372 374
373 if (width_r > 8 || width_g > 8 || width_b > 8) 375 if (width_r > 8 || width_g > 8 || width_b > 8 || width_a > 8)
374 return false; 376 return false;
375 377
376 sh_r = ecb_ctz32 (visual->red_mask); 378 sh_r = ecb_ctz32 (visual->red_mask);
377 sh_g = ecb_ctz32 (visual->green_mask); 379 sh_g = ecb_ctz32 (visual->green_mask);
378 sh_b = ecb_ctz32 (visual->blue_mask); 380 sh_b = ecb_ctz32 (visual->blue_mask);
381 sh_a = ecb_ctz32 (alpha_mask);
379 382
380 if (width > INT_MAX / height / bytes_per_pixel) 383 if (width > 32767 || height > 32767)
381 return false; 384 return false;
382 385
383 data = (char *)malloc (width * height * bytes_per_pixel); 386 ximage = XCreateImage (dpy, visual, depth, ZPixmap, 0, 0,
384 if (!data) 387 width, height, 32, 0);
388 if (!ximage)
385 return false; 389 return false;
386 390
387 ximage = XCreateImage (dpy, visual, depth, ZPixmap, 0, data, 391 if (height > INT_MAX / ximage->bytes_per_line
388 width, height, bytes_per_pixel * 8, 0); 392 || !(ximage->data = (char *)malloc (height * ximage->bytes_per_line)))
389 if (!ximage)
390 { 393 {
391 free (data); 394 XDestroyImage (ximage);
392 return false; 395 return false;
393 } 396 }
394 397
395 ximage->byte_order = ecb_big_endian () ? MSBFirst : LSBFirst; 398 ximage->byte_order = ecb_big_endian () ? MSBFirst : LSBFirst;
396 399
397 rowstride = gdk_pixbuf_get_rowstride (pixbuf); 400 rowstride = gdk_pixbuf_get_rowstride (pixbuf);
398 channels = gdk_pixbuf_get_n_channels (pixbuf); 401 channels = gdk_pixbuf_get_n_channels (pixbuf);
399 row = gdk_pixbuf_get_pixels (pixbuf) + src_y * rowstride + src_x * channels; 402 row = gdk_pixbuf_get_pixels (pixbuf) + src_y * rowstride + src_x * channels;
400 line = data; 403 line = ximage->data;
404
405 rgba c (0, 0, 0);
406
407 if (channels == 4 && alpha_mask == 0)
408 {
409 pix_colors[Color_bg].get (c);
410 c.r >>= 8;
411 c.g >>= 8;
412 c.b >>= 8;
413 }
401 414
402 for (int y = 0; y < height; y++) 415 for (int y = 0; y < height; y++)
403 { 416 {
404 for (int x = 0; x < width; x++) 417 for (int x = 0; x < width; x++)
405 { 418 {
406 unsigned char *pixel = row + x * channels; 419 unsigned char *pixel = row + x * channels;
407 uint32_t value; 420 uint32_t value;
421 unsigned char r, g, b, a;
408 422
423 if (channels == 4)
424 {
425 a = pixel[3];
426 r = (pixel[0] * a + c.r * (0xff - a)) / 0xff;
427 g = (pixel[1] * a + c.g * (0xff - a)) / 0xff;
428 b = (pixel[2] * a + c.b * (0xff - a)) / 0xff;
429 }
430 else
431 {
432 a = 0xff;
433 r = pixel[0];
434 g = pixel[1];
435 b = pixel[2];
436 }
437
409 value = ((pixel[0] >> (8 - width_r)) << sh_r) 438 value = ((r >> (8 - width_r)) << sh_r)
410 | ((pixel[1] >> (8 - width_g)) << sh_g) 439 | ((g >> (8 - width_g)) << sh_g)
411 | ((pixel[2] >> (8 - width_b)) << sh_b); 440 | ((b >> (8 - width_b)) << sh_b)
441 | ((a >> (8 - width_a)) << sh_a);
412 442
413 if (bytes_per_pixel == 4) 443 if (ximage->bits_per_pixel == 32)
414 ((uint32_t *)line)[x] = value; 444 ((uint32_t *)line)[x] = value;
415 else 445 else
416 ((uint16_t *)line)[x] = value; 446 XPutPixel (ximage, x, y, value);
417 } 447 }
418 448
419 row += rowstride; 449 row += rowstride;
420 line += ximage->bytes_per_line; 450 line += ximage->bytes_per_line;
421 } 451 }
633 663
634# endif /* BG_IMAGE_FROM_FILE */ 664# endif /* BG_IMAGE_FROM_FILE */
635 665
636# ifdef ENABLE_TRANSPARENCY 666# ifdef ENABLE_TRANSPARENCY
637bool 667bool
638rxvt_term::bg_set_transparent ()
639{
640 if (!(bg_flags & BG_IS_TRANSPARENT))
641 {
642 bg_flags |= BG_IS_TRANSPARENT;
643 return true;
644 }
645
646 return false;
647}
648
649bool
650rxvt_term::bg_set_blur (const char *geom) 668rxvt_term::bg_set_blur (const char *geom)
651{ 669{
652 bool changed = false; 670 bool changed = false;
653 unsigned int hr, vr; 671 unsigned int hr, vr;
654 int junk; 672 int junk;
672 { 690 {
673 changed = true; 691 changed = true;
674 v_blurRadius = vr; 692 v_blurRadius = vr;
675 } 693 }
676 694
677 if (h_blurRadius && v_blurRadius)
678 bg_flags |= BG_NEEDS_BLUR;
679 else
680 bg_flags &= ~BG_NEEDS_BLUR;
681
682 return changed; 695 return changed;
683}
684
685void
686rxvt_term::set_tint_shade_flags ()
687{
688 if (shade != 100 || (bg_flags & BG_TINT_SET))
689 bg_flags |= BG_NEEDS_TINT;
690 else
691 bg_flags &= ~BG_NEEDS_TINT;
692} 696}
693 697
694bool 698bool
695rxvt_term::bg_set_tint (rxvt_color &new_tint) 699rxvt_term::bg_set_tint (rxvt_color &new_tint)
696{ 700{
706 && (c.b <= 0x00ff || c.b >= 0xff00)) 710 && (c.b <= 0x00ff || c.b >= 0xff00))
707 bg_flags |= BG_TINT_BITAND; 711 bg_flags |= BG_TINT_BITAND;
708 else 712 else
709 bg_flags &= ~BG_TINT_BITAND; 713 bg_flags &= ~BG_TINT_BITAND;
710 714
711 set_tint_shade_flags ();
712 return true; 715 return true;
713 } 716 }
714 717
715 return false; 718 return false;
716} 719}
725 new_shade = 200 - (100 + new_shade); 728 new_shade = 200 - (100 + new_shade);
726 729
727 if (new_shade != shade) 730 if (new_shade != shade)
728 { 731 {
729 shade = new_shade; 732 shade = new_shade;
730 set_tint_shade_flags ();
731 return true; 733 return true;
732 } 734 }
733 735
734 return false; 736 return false;
735} 737}
1011 1013
1012 if (gc) 1014 if (gc)
1013 { 1015 {
1014 XFillRectangle (dpy, bg_pixmap, gc, 0, 0, window_width, window_height); 1016 XFillRectangle (dpy, bg_pixmap, gc, 0, 0, window_width, window_height);
1015 ret = true; 1017 ret = true;
1016 unsigned long tr_flags = bg_flags & BG_EFFECTS_FLAGS; 1018 bool need_blur = h_blurRadius && v_blurRadius;
1019 bool need_tint = shade != 100 || (bg_flags & BG_TINT_SET);
1017 1020
1018 if (!(bg_flags & BG_CLIENT_RENDER)) 1021 if (!(bg_flags & BG_CLIENT_RENDER))
1019 { 1022 {
1020 if (bg_flags & BG_NEEDS_BLUR) 1023 if (need_blur)
1021 { 1024 {
1022 if (blur_pixmap (bg_pixmap, visual, window_width, window_height, depth)) 1025 if (blur_pixmap (bg_pixmap, visual, window_width, window_height, depth))
1023 tr_flags &= ~BG_NEEDS_BLUR; 1026 need_blur = false;
1024 } 1027 }
1025 if (bg_flags & BG_NEEDS_TINT) 1028 if (need_tint)
1026 { 1029 {
1027 if (tint_pixmap (bg_pixmap, visual, window_width, window_height)) 1030 if (tint_pixmap (bg_pixmap, visual, window_width, window_height))
1028 tr_flags &= ~BG_NEEDS_TINT; 1031 need_tint = false;
1029 } 1032 }
1030 if (tr_flags & BG_NEEDS_TINT) 1033 if (need_tint)
1031 { 1034 {
1032 XImage *ximage = XGetImage (dpy, bg_pixmap, 0, 0, bg_pmap_width, bg_pmap_height, AllPlanes, ZPixmap); 1035 XImage *ximage = XGetImage (dpy, bg_pixmap, 0, 0, bg_pmap_width, bg_pmap_height, AllPlanes, ZPixmap);
1033 if (ximage) 1036 if (ximage)
1034 { 1037 {
1035 /* our own client-side tinting */ 1038 /* our own client-side tinting */
1144} 1147}
1145 1148
1146void 1149void
1147rxvt_term::tint_ximage (Visual *visual, XImage *ximage) 1150rxvt_term::tint_ximage (Visual *visual, XImage *ximage)
1148{ 1151{
1152 unsigned int size_r, size_g, size_b;
1149 int sh_r, sh_g, sh_b; 1153 int sh_r, sh_g, sh_b;
1150 uint32_t mask_r, mask_g, mask_b; 1154 uint32_t mask_r, mask_g, mask_b;
1151 uint32_t *lookup, *lookup_r, *lookup_g, *lookup_b; 1155 uint32_t *lookup, *lookup_r, *lookup_g, *lookup_b;
1152 unsigned short low; 1156 unsigned short low;
1153 int host_byte_order = ecb_big_endian () ? MSBFirst : LSBFirst; 1157 int host_byte_order = ecb_big_endian () ? MSBFirst : LSBFirst;
1158 mask_r = visual->red_mask; 1162 mask_r = visual->red_mask;
1159 mask_g = visual->green_mask; 1163 mask_g = visual->green_mask;
1160 mask_b = visual->blue_mask; 1164 mask_b = visual->blue_mask;
1161 1165
1162 /* boring lookup table pre-initialization */ 1166 /* boring lookup table pre-initialization */
1163 switch (ximage->depth) 1167 sh_r = ecb_ctz32 (mask_r);
1164 { 1168 sh_g = ecb_ctz32 (mask_g);
1165 case 15: 1169 sh_b = ecb_ctz32 (mask_b);
1166 if ((mask_r != 0x7c00) || 1170
1167 (mask_g != 0x03e0) || 1171 size_r = mask_r >> sh_r;
1168 (mask_b != 0x001f)) 1172 size_g = mask_g >> sh_g;
1173 size_b = mask_b >> sh_b;
1174
1175 if (size_r++ > 255 || size_g++ > 255 || size_b++ > 255)
1169 return; 1176 return;
1170 lookup = (uint32_t *) malloc (sizeof (uint32_t)*(32+32+32)); 1177
1178 lookup = (uint32_t *)malloc (sizeof (uint32_t) * (size_r + size_g + size_b));
1171 lookup_r = lookup; 1179 lookup_r = lookup;
1172 lookup_g = lookup+32; 1180 lookup_g = lookup + size_r;
1173 lookup_b = lookup+32+32; 1181 lookup_b = lookup + size_r + size_g;
1174 sh_r = 10;
1175 sh_g = 5;
1176 sh_b = 0;
1177 break;
1178 case 16:
1179 if ((mask_r != 0xf800) ||
1180 (mask_g != 0x07e0) ||
1181 (mask_b != 0x001f))
1182 return;
1183 lookup = (uint32_t *) malloc (sizeof (uint32_t)*(32+64+32));
1184 lookup_r = lookup;
1185 lookup_g = lookup+32;
1186 lookup_b = lookup+32+64;
1187 sh_r = 11;
1188 sh_g = 5;
1189 sh_b = 0;
1190 break;
1191 case 24:
1192 if ((mask_r != 0xff0000) ||
1193 (mask_g != 0x00ff00) ||
1194 (mask_b != 0x0000ff))
1195 return;
1196 lookup = (uint32_t *) malloc (sizeof (uint32_t)*(256+256+256));
1197 lookup_r = lookup;
1198 lookup_g = lookup+256;
1199 lookup_b = lookup+256+256;
1200 sh_r = 16;
1201 sh_g = 8;
1202 sh_b = 0;
1203 break;
1204 case 32:
1205 if ((mask_r != 0xff0000) ||
1206 (mask_g != 0x00ff00) ||
1207 (mask_b != 0x0000ff))
1208 return;
1209 lookup = (uint32_t *) malloc (sizeof (uint32_t)*(256+256+256));
1210 lookup_r = lookup;
1211 lookup_g = lookup+256;
1212 lookup_b = lookup+256+256;
1213 sh_r = 16;
1214 sh_g = 8;
1215 sh_b = 0;
1216 break;
1217 default:
1218 return; /* we do not support this color depth */
1219 }
1220 1182
1221 rgba c (rgba::MAX_CC, rgba::MAX_CC, rgba::MAX_CC); 1183 rgba c (rgba::MAX_CC, rgba::MAX_CC, rgba::MAX_CC);
1222 1184
1223 if (bg_flags & BG_TINT_SET) 1185 if (bg_flags & BG_TINT_SET)
1224 tint.get (c); 1186 tint.get (c);
1246 fill_lut (lookup_g, mask_g, sh_g, low, c.g); 1208 fill_lut (lookup_g, mask_g, sh_g, low, c.g);
1247 fill_lut (lookup_b, mask_b, sh_b, low, c.b); 1209 fill_lut (lookup_b, mask_b, sh_b, low, c.b);
1248 1210
1249 /* apply table to input image (replacing colors by newly calculated ones) */ 1211 /* apply table to input image (replacing colors by newly calculated ones) */
1250 if (ximage->bits_per_pixel == 32 1212 if (ximage->bits_per_pixel == 32
1251 && (ximage->depth == 24 || ximage->depth == 32)
1252 && ximage->byte_order == host_byte_order) 1213 && ximage->byte_order == host_byte_order)
1253 { 1214 {
1254 uint32_t *p1, *pf, *p, *pl; 1215 char *line = ximage->data;
1255 p1 = (uint32_t *) ximage->data;
1256 pf = (uint32_t *) (ximage->data + ximage->height * ximage->bytes_per_line);
1257 1216
1258 while (p1 < pf) 1217 for (int y = 0; y < ximage->height; y++)
1259 {
1260 p = p1;
1261 pl = p1 + ximage->width;
1262 for (; p < pl; p++)
1263 { 1218 {
1264 *p = lookup_r[(*p & 0xff0000) >> 16] | 1219 uint32_t *p = (uint32_t *)line;
1265 lookup_g[(*p & 0x00ff00) >> 8] | 1220 for (int x = 0; x < ximage->width; x++)
1266 lookup_b[(*p & 0x0000ff)] |
1267 (*p & 0xff000000);
1268 } 1221 {
1269 p1 = (uint32_t *) ((char *) p1 + ximage->bytes_per_line); 1222 *p = lookup_r[(*p & mask_r) >> sh_r] |
1223 lookup_g[(*p & mask_g) >> sh_g] |
1224 lookup_b[(*p & mask_b) >> sh_b];
1225 p++;
1226 }
1227 line += ximage->bytes_per_line;
1270 } 1228 }
1271 } 1229 }
1272 else 1230 else
1273 { 1231 {
1274 for (int y = 0; y < ximage->height; y++) 1232 for (int y = 0; y < ximage->height; y++)

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines