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.204 by sf-exg, Tue Apr 10 15:19:22 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.
123 123
124# ifdef BG_IMAGE_FROM_FILE 124# ifdef BG_IMAGE_FROM_FILE
125static inline int 125static inline int
126make_align_position (int align, int window_size, int image_size) 126make_align_position (int align, int window_size, int image_size)
127{ 127{
128 int diff = window_size - image_size;
129 int smaller = min (image_size, window_size);
130
131 if (align >= 0 && align <= 100) 128 if (align >= 0 && align <= 100)
132 return diff * align / 100; 129 return lerp (0, window_size - image_size, align);
133 else if (align > 100 && align <= 200) 130 else if (align > 100)
134 return (align - 100) * smaller / 100 + window_size - smaller; 131 return lerp (window_size - image_size, window_size, align - 100);
135 else if (align >= -100 && align < 0) 132 else
136 return (align + 100) * smaller / 100 - image_size; 133 return lerp (-image_size, 0, align + 100);
137 return 0;
138} 134}
139 135
140static inline int 136static inline int
141make_clip_rectangle (int pos, int size, int target_size, int &dst_pos, int &dst_size) 137make_clip_rectangle (int pos, int size, int target_size, int &dst_pos, int &dst_size)
142{ 138{
350rxvt_term::pixbuf_to_pixmap (GdkPixbuf *pixbuf, Pixmap pixmap, GC gc, 346rxvt_term::pixbuf_to_pixmap (GdkPixbuf *pixbuf, Pixmap pixmap, GC gc,
351 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,
352 unsigned int width, unsigned int height) 348 unsigned int width, unsigned int height)
353{ 349{
354 XImage *ximage; 350 XImage *ximage;
355 char *data, *line; 351 char *line;
356 int bytes_per_pixel;
357 int width_r, width_g, width_b; 352 int width_r, width_g, width_b, width_a;
358 int sh_r, sh_g, sh_b; 353 int sh_r, sh_g, sh_b, sh_a;
354 uint32_t alpha_mask;
359 int rowstride; 355 int rowstride;
360 int channels; 356 int channels;
361 unsigned char *row; 357 unsigned char *row;
362 358
363 if (visual->c_class != TrueColor) 359 if (visual->c_class != TrueColor)
364 return false; 360 return false;
365 361
366 if (depth == 24 || depth == 32) 362#if XRENDER
367 bytes_per_pixel = 4; 363 XRenderPictFormat *format = XRenderFindVisualFormat (dpy, visual);
368 else if (depth == 15 || depth == 16) 364 if (format)
369 bytes_per_pixel = 2; 365 alpha_mask = (uint32_t)format->direct.alphaMask << format->direct.alpha;
370 else 366 else
371 return false; 367#endif
368 alpha_mask = 0;
372 369
373 width_r = ecb_popcount32 (visual->red_mask); 370 width_r = ecb_popcount32 (visual->red_mask);
374 width_g = ecb_popcount32 (visual->green_mask); 371 width_g = ecb_popcount32 (visual->green_mask);
375 width_b = ecb_popcount32 (visual->blue_mask); 372 width_b = ecb_popcount32 (visual->blue_mask);
373 width_a = ecb_popcount32 (alpha_mask);
376 374
377 if (width_r > 8 || width_g > 8 || width_b > 8) 375 if (width_r > 8 || width_g > 8 || width_b > 8 || width_a > 8)
378 return false; 376 return false;
379 377
380 sh_r = ecb_ctz32 (visual->red_mask); 378 sh_r = ecb_ctz32 (visual->red_mask);
381 sh_g = ecb_ctz32 (visual->green_mask); 379 sh_g = ecb_ctz32 (visual->green_mask);
382 sh_b = ecb_ctz32 (visual->blue_mask); 380 sh_b = ecb_ctz32 (visual->blue_mask);
381 sh_a = ecb_ctz32 (alpha_mask);
383 382
384 if (width > INT_MAX / height / bytes_per_pixel) 383 if (width > 32767 || height > 32767)
385 return false; 384 return false;
386 385
387 data = (char *)malloc (width * height * bytes_per_pixel); 386 ximage = XCreateImage (dpy, visual, depth, ZPixmap, 0, 0,
388 if (!data) 387 width, height, 32, 0);
388 if (!ximage)
389 return false; 389 return false;
390 390
391 ximage = XCreateImage (dpy, visual, depth, ZPixmap, 0, data, 391 if (height > INT_MAX / ximage->bytes_per_line
392 width, height, bytes_per_pixel * 8, 0); 392 || !(ximage->data = (char *)malloc (height * ximage->bytes_per_line)))
393 if (!ximage)
394 { 393 {
395 free (data); 394 XDestroyImage (ximage);
396 return false; 395 return false;
397 } 396 }
398 397
399 ximage->byte_order = ecb_big_endian () ? MSBFirst : LSBFirst; 398 ximage->byte_order = ecb_big_endian () ? MSBFirst : LSBFirst;
400 399
401 rowstride = gdk_pixbuf_get_rowstride (pixbuf); 400 rowstride = gdk_pixbuf_get_rowstride (pixbuf);
402 channels = gdk_pixbuf_get_n_channels (pixbuf); 401 channels = gdk_pixbuf_get_n_channels (pixbuf);
403 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;
404 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 }
405 414
406 for (int y = 0; y < height; y++) 415 for (int y = 0; y < height; y++)
407 { 416 {
408 for (int x = 0; x < width; x++) 417 for (int x = 0; x < width; x++)
409 { 418 {
410 unsigned char *pixel = row + x * channels; 419 unsigned char *pixel = row + x * channels;
411 uint32_t value; 420 uint32_t value;
421 unsigned char r, g, b, a;
412 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
413 value = ((pixel[0] >> (8 - width_r)) << sh_r) 438 value = ((r >> (8 - width_r)) << sh_r)
414 | ((pixel[1] >> (8 - width_g)) << sh_g) 439 | ((g >> (8 - width_g)) << sh_g)
415 | ((pixel[2] >> (8 - width_b)) << sh_b); 440 | ((b >> (8 - width_b)) << sh_b)
441 | ((a >> (8 - width_a)) << sh_a);
416 442
417 if (bytes_per_pixel == 4) 443 if (ximage->bits_per_pixel == 32)
418 ((uint32_t *)line)[x] = value; 444 ((uint32_t *)line)[x] = value;
419 else 445 else
420 ((uint16_t *)line)[x] = value; 446 XPutPixel (ximage, x, y, value);
421 } 447 }
422 448
423 row += rowstride; 449 row += rowstride;
424 line += ximage->bytes_per_line; 450 line += ximage->bytes_per_line;
425 } 451 }
637 663
638# endif /* BG_IMAGE_FROM_FILE */ 664# endif /* BG_IMAGE_FROM_FILE */
639 665
640# ifdef ENABLE_TRANSPARENCY 666# ifdef ENABLE_TRANSPARENCY
641bool 667bool
642rxvt_term::bg_set_transparent ()
643{
644 if (!(bg_flags & BG_IS_TRANSPARENT))
645 {
646 bg_flags |= BG_IS_TRANSPARENT;
647 return true;
648 }
649
650 return false;
651}
652
653bool
654rxvt_term::bg_set_blur (const char *geom) 668rxvt_term::bg_set_blur (const char *geom)
655{ 669{
656 bool changed = false; 670 bool changed = false;
657 unsigned int hr, vr; 671 unsigned int hr, vr;
658 int junk; 672 int junk;
676 { 690 {
677 changed = true; 691 changed = true;
678 v_blurRadius = vr; 692 v_blurRadius = vr;
679 } 693 }
680 694
681 if (h_blurRadius && v_blurRadius)
682 bg_flags |= BG_NEEDS_BLUR;
683 else
684 bg_flags &= ~BG_NEEDS_BLUR;
685
686 return changed; 695 return changed;
687}
688
689void
690rxvt_term::set_tint_shade_flags ()
691{
692 if (shade != 100 || (bg_flags & BG_TINT_SET))
693 bg_flags |= BG_NEEDS_TINT;
694 else
695 bg_flags &= ~BG_NEEDS_TINT;
696} 696}
697 697
698bool 698bool
699rxvt_term::bg_set_tint (rxvt_color &new_tint) 699rxvt_term::bg_set_tint (rxvt_color &new_tint)
700{ 700{
710 && (c.b <= 0x00ff || c.b >= 0xff00)) 710 && (c.b <= 0x00ff || c.b >= 0xff00))
711 bg_flags |= BG_TINT_BITAND; 711 bg_flags |= BG_TINT_BITAND;
712 else 712 else
713 bg_flags &= ~BG_TINT_BITAND; 713 bg_flags &= ~BG_TINT_BITAND;
714 714
715 set_tint_shade_flags ();
716 return true; 715 return true;
717 } 716 }
718 717
719 return false; 718 return false;
720} 719}
729 new_shade = 200 - (100 + new_shade); 728 new_shade = 200 - (100 + new_shade);
730 729
731 if (new_shade != shade) 730 if (new_shade != shade)
732 { 731 {
733 shade = new_shade; 732 shade = new_shade;
734 set_tint_shade_flags ();
735 return true; 733 return true;
736 } 734 }
737 735
738 return false; 736 return false;
739} 737}
1015 1013
1016 if (gc) 1014 if (gc)
1017 { 1015 {
1018 XFillRectangle (dpy, bg_pixmap, gc, 0, 0, window_width, window_height); 1016 XFillRectangle (dpy, bg_pixmap, gc, 0, 0, window_width, window_height);
1019 ret = true; 1017 ret = true;
1020 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);
1021 1020
1022 if (!(bg_flags & BG_CLIENT_RENDER)) 1021 if (!(bg_flags & BG_CLIENT_RENDER))
1023 { 1022 {
1024 if (bg_flags & BG_NEEDS_BLUR) 1023 if (need_blur)
1025 { 1024 {
1026 if (blur_pixmap (bg_pixmap, visual, window_width, window_height, depth)) 1025 if (blur_pixmap (bg_pixmap, visual, window_width, window_height, depth))
1027 tr_flags &= ~BG_NEEDS_BLUR; 1026 need_blur = false;
1028 } 1027 }
1029 if (bg_flags & BG_NEEDS_TINT) 1028 if (need_tint)
1030 { 1029 {
1031 if (tint_pixmap (bg_pixmap, visual, window_width, window_height)) 1030 if (tint_pixmap (bg_pixmap, visual, window_width, window_height))
1032 tr_flags &= ~BG_NEEDS_TINT; 1031 need_tint = false;
1033 } 1032 }
1034 if (tr_flags & BG_NEEDS_TINT) 1033 if (need_tint)
1035 { 1034 {
1036 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);
1037 if (ximage) 1036 if (ximage)
1038 { 1037 {
1039 /* our own client-side tinting */ 1038 /* our own client-side tinting */
1148} 1147}
1149 1148
1150void 1149void
1151rxvt_term::tint_ximage (Visual *visual, XImage *ximage) 1150rxvt_term::tint_ximage (Visual *visual, XImage *ximage)
1152{ 1151{
1152 unsigned int size_r, size_g, size_b;
1153 int sh_r, sh_g, sh_b; 1153 int sh_r, sh_g, sh_b;
1154 uint32_t mask_r, mask_g, mask_b; 1154 uint32_t mask_r, mask_g, mask_b;
1155 uint32_t *lookup, *lookup_r, *lookup_g, *lookup_b; 1155 uint32_t *lookup, *lookup_r, *lookup_g, *lookup_b;
1156 unsigned short low; 1156 unsigned short low;
1157 int host_byte_order = ecb_big_endian () ? MSBFirst : LSBFirst; 1157 int host_byte_order = ecb_big_endian () ? MSBFirst : LSBFirst;
1162 mask_r = visual->red_mask; 1162 mask_r = visual->red_mask;
1163 mask_g = visual->green_mask; 1163 mask_g = visual->green_mask;
1164 mask_b = visual->blue_mask; 1164 mask_b = visual->blue_mask;
1165 1165
1166 /* boring lookup table pre-initialization */ 1166 /* boring lookup table pre-initialization */
1167 switch (ximage->depth) 1167 sh_r = ecb_ctz32 (mask_r);
1168 { 1168 sh_g = ecb_ctz32 (mask_g);
1169 case 15: 1169 sh_b = ecb_ctz32 (mask_b);
1170 if ((mask_r != 0x7c00) || 1170
1171 (mask_g != 0x03e0) || 1171 size_r = mask_r >> sh_r;
1172 (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)
1173 return; 1176 return;
1174 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));
1175 lookup_r = lookup; 1179 lookup_r = lookup;
1176 lookup_g = lookup+32; 1180 lookup_g = lookup + size_r;
1177 lookup_b = lookup+32+32; 1181 lookup_b = lookup + size_r + size_g;
1178 sh_r = 10;
1179 sh_g = 5;
1180 sh_b = 0;
1181 break;
1182 case 16:
1183 if ((mask_r != 0xf800) ||
1184 (mask_g != 0x07e0) ||
1185 (mask_b != 0x001f))
1186 return;
1187 lookup = (uint32_t *) malloc (sizeof (uint32_t)*(32+64+32));
1188 lookup_r = lookup;
1189 lookup_g = lookup+32;
1190 lookup_b = lookup+32+64;
1191 sh_r = 11;
1192 sh_g = 5;
1193 sh_b = 0;
1194 break;
1195 case 24:
1196 if ((mask_r != 0xff0000) ||
1197 (mask_g != 0x00ff00) ||
1198 (mask_b != 0x0000ff))
1199 return;
1200 lookup = (uint32_t *) malloc (sizeof (uint32_t)*(256+256+256));
1201 lookup_r = lookup;
1202 lookup_g = lookup+256;
1203 lookup_b = lookup+256+256;
1204 sh_r = 16;
1205 sh_g = 8;
1206 sh_b = 0;
1207 break;
1208 case 32:
1209 if ((mask_r != 0xff0000) ||
1210 (mask_g != 0x00ff00) ||
1211 (mask_b != 0x0000ff))
1212 return;
1213 lookup = (uint32_t *) malloc (sizeof (uint32_t)*(256+256+256));
1214 lookup_r = lookup;
1215 lookup_g = lookup+256;
1216 lookup_b = lookup+256+256;
1217 sh_r = 16;
1218 sh_g = 8;
1219 sh_b = 0;
1220 break;
1221 default:
1222 return; /* we do not support this color depth */
1223 }
1224 1182
1225 rgba c (rgba::MAX_CC, rgba::MAX_CC, rgba::MAX_CC); 1183 rgba c (rgba::MAX_CC, rgba::MAX_CC, rgba::MAX_CC);
1226 1184
1227 if (bg_flags & BG_TINT_SET) 1185 if (bg_flags & BG_TINT_SET)
1228 tint.get (c); 1186 tint.get (c);
1250 fill_lut (lookup_g, mask_g, sh_g, low, c.g); 1208 fill_lut (lookup_g, mask_g, sh_g, low, c.g);
1251 fill_lut (lookup_b, mask_b, sh_b, low, c.b); 1209 fill_lut (lookup_b, mask_b, sh_b, low, c.b);
1252 1210
1253 /* apply table to input image (replacing colors by newly calculated ones) */ 1211 /* apply table to input image (replacing colors by newly calculated ones) */
1254 if (ximage->bits_per_pixel == 32 1212 if (ximage->bits_per_pixel == 32
1255 && (ximage->depth == 24 || ximage->depth == 32)
1256 && ximage->byte_order == host_byte_order) 1213 && ximage->byte_order == host_byte_order)
1257 { 1214 {
1258 uint32_t *p1, *pf, *p, *pl; 1215 char *line = ximage->data;
1259 p1 = (uint32_t *) ximage->data;
1260 pf = (uint32_t *) (ximage->data + ximage->height * ximage->bytes_per_line);
1261 1216
1262 while (p1 < pf) 1217 for (int y = 0; y < ximage->height; y++)
1263 {
1264 p = p1;
1265 pl = p1 + ximage->width;
1266 for (; p < pl; p++)
1267 { 1218 {
1268 *p = lookup_r[(*p & 0xff0000) >> 16] | 1219 uint32_t *p = (uint32_t *)line;
1269 lookup_g[(*p & 0x00ff00) >> 8] | 1220 for (int x = 0; x < ximage->width; x++)
1270 lookup_b[(*p & 0x0000ff)] |
1271 (*p & 0xff000000);
1272 } 1221 {
1273 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;
1274 } 1228 }
1275 } 1229 }
1276 else 1230 else
1277 { 1231 {
1278 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