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.187 by sf-exg, Wed Dec 28 13:13:33 2011 UTC vs.
Revision 1.208 by sf-exg, Fri May 11 08:16:58 2012 UTC

20 * You should have received a copy of the GNU General Public License 20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software 21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 22 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23 *---------------------------------------------------------------------*/ 23 *---------------------------------------------------------------------*/
24 24
25#include <cmath> 25#include <math.h>
26#include "../config.h" /* NECESSARY */ 26#include "../config.h" /* NECESSARY */
27#include "rxvt.h" /* NECESSARY */ 27#include "rxvt.h" /* NECESSARY */
28 28
29#if XRENDER 29#if XRENDER
30# include <X11/extensions/Xrender.h> 30# include <X11/extensions/Xrender.h>
32 32
33#ifndef FilterConvolution 33#ifndef FilterConvolution
34#define FilterConvolution "convolution" 34#define FilterConvolution "convolution"
35#endif 35#endif
36 36
37#ifndef RepeatPad
38#define RepeatPad True
39#endif
40
37#ifdef HAVE_BG_PIXMAP 41#ifdef HAVE_BG_PIXMAP
42# if XRENDER
43static Picture
44create_xrender_mask (Display *dpy, Drawable drawable, Bool argb, Bool component_alpha)
45{
46 Pixmap pixmap = XCreatePixmap (dpy, drawable, 1, 1, argb ? 32 : 8);
47
48 XRenderPictFormat *format = XRenderFindStandardFormat (dpy, argb ? PictStandardARGB32 : PictStandardA8);
49 XRenderPictureAttributes pa;
50 pa.repeat = True;
51 pa.component_alpha = component_alpha;
52 Picture mask = XRenderCreatePicture (dpy, pixmap, format, CPRepeat | CPComponentAlpha, &pa);
53
54 XFreePixmap (dpy, pixmap);
55
56 return mask;
57}
58# endif
59
38void 60void
39rxvt_term::bg_destroy () 61rxvt_term::bg_destroy ()
40{ 62{
41#ifdef HAVE_AFTERIMAGE
42 if (original_asim)
43 safe_asimage_destroy (original_asim);
44 if (asv)
45 destroy_asvisual (asv, 0);
46 if (asimman)
47 destroy_image_manager (asimman, 0);
48#endif
49
50#ifdef HAVE_PIXBUF 63#ifdef HAVE_PIXBUF
51 if (pixbuf) 64 if (pixbuf)
52 g_object_unref (pixbuf); 65 g_object_unref (pixbuf);
53#endif 66#endif
54 67
107 120
108 return false; 121 return false;
109} 122}
110 123
111# ifdef BG_IMAGE_FROM_FILE 124# ifdef BG_IMAGE_FROM_FILE
112static inline bool
113check_set_scale_value (int geom_flags, int flag, unsigned int &scale, unsigned int new_value)
114{
115 if (geom_flags & flag)
116 {
117 if (new_value > 1000)
118 new_value = 1000;
119 if (new_value != scale)
120 {
121 scale = new_value;
122 return true;
123 }
124 }
125 return false;
126}
127
128static inline bool
129check_set_align_value (int geom_flags, int flag, int &align, int new_value)
130{
131 if (geom_flags & flag)
132 {
133 if (new_value < -100)
134 new_value = -100;
135 else if (new_value > 200)
136 new_value = 200;
137 if (new_value != align)
138 {
139 align = new_value;
140 return true;
141 }
142 }
143 return false;
144}
145
146static inline int 125static inline int
147make_align_position (int align, int window_size, int image_size) 126make_align_position (int align, int window_size, int image_size)
148{ 127{
149 int diff = window_size - image_size;
150 int smaller = min (image_size, window_size);
151
152 if (align >= 0 && align <= 100) 128 if (align >= 0 && align <= 100)
153 return diff * align / 100; 129 return lerp (0, window_size - image_size, align);
154 else if (align > 100 && align <= 200) 130 else if (align > 100)
155 return (align - 100) * smaller / 100 + window_size - smaller; 131 return lerp (window_size - image_size, window_size, align - 100);
156 else if (align >= -100 && align < 0) 132 else
157 return (align + 100) * smaller / 100 - image_size; 133 return lerp (-image_size, 0, align + 100);
158 return 0;
159} 134}
160 135
161static inline int 136static inline int
162make_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)
163{ 138{
169 src_pos = -pos; 144 src_pos = -pos;
170 dst_pos = 0; 145 dst_pos = 0;
171 dst_size += pos; 146 dst_size += pos;
172 } 147 }
173 148
174 if (dst_pos + dst_size > target_size)
175 dst_size = target_size - dst_pos; 149 min_it (dst_size, target_size - dst_pos);
176 return src_pos; 150 return src_pos;
177} 151}
178 152
179bool 153bool
180rxvt_term::bg_set_geometry (const char *geom, bool update) 154rxvt_term::bg_set_geometry (const char *geom, bool update)
181{ 155{
182 bool changed = false; 156 bool changed = false;
183 int geom_flags = 0; 157 int geom_flags = 0;
184 int x = 0, y = 0; 158 int x = h_align;
159 int y = v_align;
185 unsigned int w = 0, h = 0; 160 unsigned int w = h_scale;
161 unsigned int h = v_scale;
186 unsigned long new_flags = 0; 162 unsigned long new_flags = 0;
187 163
188 if (geom == NULL) 164 if (geom == NULL)
189 return false; 165 return false;
190 166
299 w = h = defaultScale; 275 w = h = defaultScale;
300 else if (!(geom_flags & HeightValue)) 276 else if (!(geom_flags & HeightValue))
301 h = w; 277 h = w;
302 else if (!(geom_flags & WidthValue)) 278 else if (!(geom_flags & WidthValue))
303 w = h; 279 w = h;
304
305 geom_flags |= WidthValue|HeightValue|XValue|YValue;
306 } 280 }
307 281
308 if (check_set_scale_value (geom_flags, WidthValue, h_scale, w)) changed = true; 282 min_it (w, 1000);
309 if (check_set_scale_value (geom_flags, HeightValue, v_scale, h)) changed = true; 283 min_it (h, 1000);
310 if (check_set_align_value (geom_flags, XValue, h_align, x)) changed = true; 284 clamp_it (x, -100, 200);
311 if (check_set_align_value (geom_flags, YValue, v_align, y)) changed = true; 285 clamp_it (y, -100, 200);
312 286
313 if (new_flags != bg_flags) 287 if (bg_flags != new_flags
288 || h_scale != w
289 || v_scale != h
290 || h_align != x
291 || v_align != y)
314 { 292 {
315 bg_flags = new_flags; 293 bg_flags = new_flags;
294 h_scale = w;
295 v_scale = h;
296 h_align = x;
297 v_align = y;
316 changed = true; 298 changed = true;
317 } 299 }
318 300
319 return changed; 301 return changed;
320} 302}
348 { 330 {
349 x = make_align_position (h_align, target_width, w); 331 x = make_align_position (h_align, target_width, w);
350 y = make_align_position (v_align, target_height, h); 332 y = make_align_position (v_align, target_height, h);
351 } 333 }
352 334
353 bg_flags &= ~BG_IS_SIZE_SENSITIVE;
354 if (!(bg_flags & BG_TILE) 335 if (!(bg_flags & BG_TILE)
355 || h_scale || v_scale 336 || h_scale || v_scale
356 || (!(bg_flags & BG_ROOT_ALIGN) && (h_align || v_align)) 337 || (!(bg_flags & BG_ROOT_ALIGN) && (h_align || v_align))
357 || w > target_width || h > target_height) 338 || image_width > target_width || image_height > target_height)
358 bg_flags |= BG_IS_SIZE_SENSITIVE; 339 bg_flags |= BG_IS_SIZE_SENSITIVE;
359}
360
361# ifdef HAVE_AFTERIMAGE
362bool
363rxvt_term::render_image (unsigned long tr_flags)
364{
365 init_asv ();
366
367 ASImage *background = NULL;
368 ARGB32 background_tint = TINT_LEAVE_SAME;
369
370# ifdef ENABLE_TRANSPARENCY
371 if (tr_flags)
372 background = pixmap2ximage (asv, bg_pixmap, 0, 0, bg_pmap_width, bg_pmap_height, AllPlanes, 100);
373
374 if (tr_flags & BG_NEEDS_TINT)
375 {
376 ShadingInfo as_shade;
377 as_shade.shading = shade;
378
379 rgba c;
380 tint.get (c);
381 as_shade.tintColor.red = c.r;
382 as_shade.tintColor.green = c.g;
383 as_shade.tintColor.blue = c.b;
384
385 background_tint = shading2tint32 (&as_shade);
386 }
387
388 if ((tr_flags & BG_NEEDS_BLUR) && background != NULL)
389 {
390 ASImage *tmp = blur_asimage_gauss (asv, background, h_blurRadius, v_blurRadius, 0xFFFFFFFF,
391 ASA_XImage,
392 100, ASIMAGE_QUALITY_DEFAULT);
393 if (tmp)
394 {
395 destroy_asimage (&background);
396 background = tmp;
397 }
398 }
399# endif
400
401 ASImage *result = 0;
402
403 int target_width = szHint.width;
404 int target_height = szHint.height;
405 int new_pmap_width = target_width;
406 int new_pmap_height = target_height;
407
408 int x = 0;
409 int y = 0;
410 int w = 0;
411 int h = 0;
412
413 if (original_asim)
414 get_image_geometry (original_asim->width, original_asim->height, w, h, x, y);
415
416 if (!original_asim
417 || (!(bg_flags & BG_ROOT_ALIGN)
418 && (x >= target_width
419 || y >= target_height
420 || x + w <= 0
421 || y + h <= 0)))
422 {
423 if (background)
424 {
425 new_pmap_width = background->width;
426 new_pmap_height = background->height;
427 result = background;
428
429 if (background_tint != TINT_LEAVE_SAME)
430 {
431 ASImage *tmp = tile_asimage (asv, background, 0, 0,
432 target_width, target_height, background_tint,
433 ASA_XImage, 100, ASIMAGE_QUALITY_DEFAULT);
434 if (tmp)
435 result = tmp;
436 }
437 }
438 else
439 new_pmap_width = new_pmap_height = 0;
440 }
441 else 340 else
442 { 341 bg_flags &= ~BG_IS_SIZE_SENSITIVE;
443 result = original_asim;
444
445 if (w != original_asim->width
446 || h != original_asim->height)
447 {
448 result = scale_asimage (asv, original_asim,
449 w, h,
450 ASA_XImage,
451 100, ASIMAGE_QUALITY_DEFAULT);
452 }
453
454 if (background == NULL)
455 {
456 if (bg_flags & BG_TILE)
457 {
458 /* if tiling - pixmap has to be sized exactly as the image,
459 but there is no need to make it bigger than the window! */
460 new_pmap_width = min (result->width, target_width);
461 new_pmap_height = min (result->height, target_height);
462
463 /* we also need to tile our image in both directions */
464 ASImage *tmp = tile_asimage (asv, result,
465 (int)result->width - x,
466 (int)result->height - y,
467 new_pmap_width,
468 new_pmap_height,
469 TINT_LEAVE_SAME, ASA_XImage,
470 100, ASIMAGE_QUALITY_DEFAULT);
471 if (tmp)
472 {
473 if (result != original_asim)
474 destroy_asimage (&result);
475
476 result = tmp;
477 }
478 }
479 }
480 else
481 {
482 /* if blending background and image - pixmap has to be sized same as target window */
483 ASImageLayer *layers = create_image_layers (2);
484
485 layers[0].im = background;
486 layers[0].clip_width = target_width;
487 layers[0].clip_height = target_height;
488 layers[0].tint = background_tint;
489 layers[1].im = result;
490
491 if (bg_flags & BG_TILE)
492 {
493 /* tile horizontally */
494 while (x > 0) x -= (int)result->width;
495 layers[1].dst_x = x;
496 layers[1].clip_width = result->width+target_width;
497 }
498 else
499 {
500 /* clip horizontally */
501 layers[1].dst_x = x;
502 layers[1].clip_width = result->width;
503 }
504
505 if (bg_flags & BG_TILE)
506 {
507 while (y > 0) y -= (int)result->height;
508 layers[1].dst_y = y;
509 layers[1].clip_height = result->height + target_height;
510 }
511 else
512 {
513 layers[1].dst_y = y;
514 layers[1].clip_height = result->height;
515 }
516
517 if (rs[Rs_blendtype])
518 {
519 layers[1].merge_scanlines = blend_scanlines_name2func (rs[Rs_blendtype]);
520 if (layers[1].merge_scanlines == NULL)
521 layers[1].merge_scanlines = alphablend_scanlines;
522 }
523
524 ASImage *tmp = merge_layers (asv, layers, 2, target_width, target_height,
525 ASA_XImage, 0, ASIMAGE_QUALITY_DEFAULT);
526
527 if (tmp)
528 {
529 if (result != original_asim)
530 destroy_asimage (&result);
531
532 result = tmp;
533 }
534
535 free (layers);
536 }
537 }
538
539 bool ret = false;
540
541 if (result)
542 {
543 XGCValues gcv;
544 GC gc;
545
546 /* create Pixmap */
547 if (bg_pixmap == None
548 || bg_pmap_width != new_pmap_width
549 || bg_pmap_height != new_pmap_height)
550 {
551 if (bg_pixmap)
552 XFreePixmap (dpy, bg_pixmap);
553 bg_pixmap = XCreatePixmap (dpy, vt, new_pmap_width, new_pmap_height, depth);
554 bg_pmap_width = new_pmap_width;
555 bg_pmap_height = new_pmap_height;
556 }
557 /* fill with background color (if result's not completely overlapping it) */
558 gcv.foreground = pix_colors[Color_bg];
559 gc = XCreateGC (dpy, vt, GCForeground, &gcv);
560
561 int src_x = 0, src_y = 0, dst_x = 0, dst_y = 0;
562 int dst_width = result->width, dst_height = result->height;
563 if (background == NULL)
564 {
565 if (!(bg_flags & BG_TILE))
566 {
567 src_x = make_clip_rectangle (x, result->width , new_pmap_width , dst_x, dst_width );
568 src_y = make_clip_rectangle (y, result->height, new_pmap_height, dst_y, dst_height);
569 }
570
571 if (dst_x > 0 || dst_y > 0
572 || dst_x + dst_width < new_pmap_width
573 || dst_y + dst_height < new_pmap_height)
574 XFillRectangle (dpy, bg_pixmap, gc, 0, 0, new_pmap_width, new_pmap_height);
575 }
576
577 /* put result on pixmap */
578 if (dst_x < new_pmap_width && dst_y < new_pmap_height)
579 asimage2drawable (asv, bg_pixmap, result, gc, src_x, src_y, dst_x, dst_y, dst_width, dst_height, True);
580
581 if (result != background && result != original_asim)
582 destroy_asimage (&result);
583
584 XFreeGC (dpy, gc);
585
586 ret = true;
587 }
588
589 if (background)
590 destroy_asimage (&background);
591
592 return ret;
593} 342}
594# endif /* HAVE_AFTERIMAGE */
595 343
596# ifdef HAVE_PIXBUF 344# ifdef HAVE_PIXBUF
597bool 345bool
598rxvt_term::pixbuf_to_pixmap (GdkPixbuf *pixbuf, Pixmap pixmap, GC gc, 346rxvt_term::pixbuf_to_pixmap (GdkPixbuf *pixbuf, Pixmap pixmap, GC gc,
599 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,
600 unsigned int width, unsigned int height) 348 unsigned int width, unsigned int height)
601{ 349{
602 XImage *ximage; 350 XImage *ximage;
603 char *data, *line; 351 char *data, *line;
604 int bytes_per_pixel; 352 int bytes_per_pixel;
605 int width_r, width_g, width_b; 353 int width_r, width_g, width_b, width_a;
606 int sh_r, sh_g, sh_b; 354 int sh_r, sh_g, sh_b, sh_a;
355 uint32_t alpha_mask;
607 int rowstride; 356 int rowstride;
608 int channels; 357 int channels;
609 unsigned char *row; 358 unsigned char *row;
610 359
611 if (visual->c_class != TrueColor) 360 if (visual->c_class != TrueColor)
612 return false; 361 return false;
362
363#if XRENDER
364 XRenderPictFormat *format = XRenderFindVisualFormat (dpy, visual);
365 if (format)
366 alpha_mask = (uint32_t)format->direct.alphaMask << format->direct.alpha;
367 else
368#endif
369 alpha_mask = 0;
613 370
614 if (depth == 24 || depth == 32) 371 if (depth == 24 || depth == 32)
615 bytes_per_pixel = 4; 372 bytes_per_pixel = 4;
616 else if (depth == 15 || depth == 16) 373 else if (depth == 15 || depth == 16)
617 bytes_per_pixel = 2; 374 bytes_per_pixel = 2;
619 return false; 376 return false;
620 377
621 width_r = ecb_popcount32 (visual->red_mask); 378 width_r = ecb_popcount32 (visual->red_mask);
622 width_g = ecb_popcount32 (visual->green_mask); 379 width_g = ecb_popcount32 (visual->green_mask);
623 width_b = ecb_popcount32 (visual->blue_mask); 380 width_b = ecb_popcount32 (visual->blue_mask);
381 width_a = ecb_popcount32 (alpha_mask);
624 382
625 if (width_r > 8 || width_g > 8 || width_b > 8) 383 if (width_r > 8 || width_g > 8 || width_b > 8 || width_a > 8)
626 return false; 384 return false;
627 385
628 sh_r = ecb_ctz32 (visual->red_mask); 386 sh_r = ecb_ctz32 (visual->red_mask);
629 sh_g = ecb_ctz32 (visual->green_mask); 387 sh_g = ecb_ctz32 (visual->green_mask);
630 sh_b = ecb_ctz32 (visual->blue_mask); 388 sh_b = ecb_ctz32 (visual->blue_mask);
389 sh_a = ecb_ctz32 (alpha_mask);
631 390
632 if (width > INT_MAX / height / bytes_per_pixel) 391 if (width > INT_MAX / height / bytes_per_pixel)
633 return false; 392 return false;
634 393
635 data = (char *)malloc (width * height * bytes_per_pixel); 394 data = (char *)malloc (width * height * bytes_per_pixel);
649 rowstride = gdk_pixbuf_get_rowstride (pixbuf); 408 rowstride = gdk_pixbuf_get_rowstride (pixbuf);
650 channels = gdk_pixbuf_get_n_channels (pixbuf); 409 channels = gdk_pixbuf_get_n_channels (pixbuf);
651 row = gdk_pixbuf_get_pixels (pixbuf) + src_y * rowstride + src_x * channels; 410 row = gdk_pixbuf_get_pixels (pixbuf) + src_y * rowstride + src_x * channels;
652 line = data; 411 line = data;
653 412
413 rgba c (0, 0, 0);
414
415 if (channels == 4 && alpha_mask == 0)
416 {
417 pix_colors[Color_bg].get (c);
418 c.r >>= 8;
419 c.g >>= 8;
420 c.b >>= 8;
421 }
422
654 for (int y = 0; y < height; y++) 423 for (int y = 0; y < height; y++)
655 { 424 {
656 for (int x = 0; x < width; x++) 425 for (int x = 0; x < width; x++)
657 { 426 {
658 unsigned char *pixel = row + x * channels; 427 unsigned char *pixel = row + x * channels;
659 uint32_t value; 428 uint32_t value;
429 unsigned char r, g, b, a;
660 430
431 if (channels == 4)
432 {
433 a = pixel[3];
434 r = (pixel[0] * a + c.r * (0xff - a)) / 0xff;
435 g = (pixel[1] * a + c.g * (0xff - a)) / 0xff;
436 b = (pixel[2] * a + c.b * (0xff - a)) / 0xff;
437 }
438 else
439 {
440 a = 0xff;
441 r = pixel[0];
442 g = pixel[1];
443 b = pixel[2];
444 }
445
661 value = ((pixel[0] >> (8 - width_r)) << sh_r) 446 value = ((r >> (8 - width_r)) << sh_r)
662 | ((pixel[1] >> (8 - width_g)) << sh_g) 447 | ((g >> (8 - width_g)) << sh_g)
663 | ((pixel[2] >> (8 - width_b)) << sh_b); 448 | ((b >> (8 - width_b)) << sh_b)
449 | ((a >> (8 - width_a)) << sh_a);
664 450
665 if (bytes_per_pixel == 4) 451 if (bytes_per_pixel == 4)
666 ((uint32_t *)line)[x] = value; 452 ((uint32_t *)line)[x] = value;
667 else 453 else
668 ((uint16_t *)line)[x] = value; 454 ((uint16_t *)line)[x] = value;
676 XDestroyImage (ximage); 462 XDestroyImage (ximage);
677 return true; 463 return true;
678} 464}
679 465
680bool 466bool
681rxvt_term::render_image (unsigned long tr_flags) 467rxvt_term::render_image (bool transparent)
682{ 468{
683 if (!pixbuf) 469 if (!pixbuf)
684 return false; 470 return false;
685 471
686 if (tr_flags 472 if (transparent
687 && !(bg_flags & BG_HAS_RENDER)) 473 && !(bg_flags & BG_HAS_RENDER))
688 return false; 474 return false;
689 475
690 GdkPixbuf *result; 476 GdkPixbuf *result;
691 477
731 Pixmap root_pmap; 517 Pixmap root_pmap;
732 518
733 image_width = gdk_pixbuf_get_width (result); 519 image_width = gdk_pixbuf_get_width (result);
734 image_height = gdk_pixbuf_get_height (result); 520 image_height = gdk_pixbuf_get_height (result);
735 521
736 if (tr_flags) 522 if (transparent)
737 { 523 {
738 root_pmap = bg_pixmap; 524 root_pmap = bg_pixmap;
739 bg_pixmap = None; 525 bg_pixmap = None;
740 } 526 }
741 else 527 else
799 dst_x, dst_y, 585 dst_x, dst_y,
800 dst_width, dst_height); 586 dst_width, dst_height);
801 } 587 }
802 588
803#if XRENDER 589#if XRENDER
804 if (tr_flags) 590 if (transparent)
805 { 591 {
806 XRenderPictureAttributes pa;
807
808 XRenderPictFormat *src_format = XRenderFindVisualFormat (dpy, visual); 592 XRenderPictFormat *format = XRenderFindVisualFormat (dpy, visual);
593
809 Picture src = XRenderCreatePicture (dpy, root_pmap, src_format, 0, &pa); 594 Picture src = XRenderCreatePicture (dpy, root_pmap, format, 0, 0);
810 595
811 XRenderPictFormat *dst_format = XRenderFindVisualFormat (dpy, visual);
812 Picture dst = XRenderCreatePicture (dpy, bg_pixmap, dst_format, 0, &pa); 596 Picture dst = XRenderCreatePicture (dpy, bg_pixmap, format, 0, 0);
813 597
814 pa.repeat = True; 598 Picture mask = create_xrender_mask (dpy, vt, False, False);
815 Pixmap mask_pmap = XCreatePixmap (dpy, vt, 1, 1, 8);
816 XRenderPictFormat *mask_format = XRenderFindStandardFormat (dpy, PictStandardA8);
817 Picture mask = XRenderCreatePicture (dpy, mask_pmap, mask_format, CPRepeat, &pa);
818 XFreePixmap (dpy, mask_pmap);
819 599
820 XRenderColor mask_c; 600 XRenderColor mask_c;
821 601
822 mask_c.alpha = 0x8000; 602 mask_c.alpha = 0x8000;
823 mask_c.red = 0; 603 mask_c.red =
824 mask_c.green = 0; 604 mask_c.green =
825 mask_c.blue = 0; 605 mask_c.blue = 0;
826 XRenderFillRectangle (dpy, PictOpSrc, mask, &mask_c, 0, 0, 1, 1); 606 XRenderFillRectangle (dpy, PictOpSrc, mask, &mask_c, 0, 0, 1, 1);
607
827 XRenderComposite (dpy, PictOpOver, src, mask, dst, 0, 0, 0, 0, 0, 0, target_width, target_height); 608 XRenderComposite (dpy, PictOpOver, src, mask, dst, 0, 0, 0, 0, 0, 0, target_width, target_height);
828 609
829 XRenderFreePicture (dpy, src); 610 XRenderFreePicture (dpy, src);
830 XRenderFreePicture (dpy, dst); 611 XRenderFreePicture (dpy, dst);
831 XRenderFreePicture (dpy, mask); 612 XRenderFreePicture (dpy, mask);
838 } 619 }
839 620
840 if (result != pixbuf) 621 if (result != pixbuf)
841 g_object_unref (result); 622 g_object_unref (result);
842 623
843 if (tr_flags) 624 if (transparent)
844 XFreePixmap (dpy, root_pmap); 625 XFreePixmap (dpy, root_pmap);
845 626
846 return ret; 627 return ret;
847} 628}
848# endif /* HAVE_PIXBUF */ 629# endif /* HAVE_PIXBUF */
863 memcpy (f, file, len); 644 memcpy (f, file, len);
864 f[len] = '\0'; 645 f[len] = '\0';
865 file = f; 646 file = f;
866 } 647 }
867 648
868# ifdef HAVE_AFTERIMAGE
869 if (!asimman)
870 asimman = create_generic_imageman (rs[Rs_path]);
871 ASImage *image = get_asimage (asimman, file, 0xFFFFFFFF, 100);
872 if (image)
873 {
874 if (original_asim)
875 safe_asimage_destroy (original_asim);
876 original_asim = image;
877 bg_flags |= BG_IS_FROM_FILE | BG_CLIENT_RENDER;
878 ret = true;
879 }
880# endif
881
882# ifdef HAVE_PIXBUF 649# ifdef HAVE_PIXBUF
883 GdkPixbuf *image = gdk_pixbuf_new_from_file (file, NULL); 650 GdkPixbuf *image = gdk_pixbuf_new_from_file (file, NULL);
884 if (image) 651 if (image)
885 { 652 {
886 if (pixbuf) 653 if (pixbuf)
943 { 710 {
944 changed = true; 711 changed = true;
945 v_blurRadius = vr; 712 v_blurRadius = vr;
946 } 713 }
947 714
948 if (v_blurRadius == 0 && h_blurRadius == 0) 715 if (h_blurRadius && v_blurRadius)
716 bg_flags |= BG_NEEDS_BLUR;
717 else
949 bg_flags &= ~BG_NEEDS_BLUR; 718 bg_flags &= ~BG_NEEDS_BLUR;
950 else
951 bg_flags |= BG_NEEDS_BLUR;
952 719
953 return changed; 720 return changed;
954} 721}
955 722
956void 723void
957rxvt_term::set_tint_shade_flags () 724rxvt_term::set_tint_shade_flags ()
958{ 725{
959 rgba c; 726 if (shade != 100 || (bg_flags & BG_TINT_SET))
960 bool has_shade = shade != 100;
961
962 bg_flags &= ~BG_TINT_FLAGS;
963
964 tint.get (c);
965
966 if (!has_shade
967 && (c.r <= 0x00ff || c.r >= 0xff00)
968 && (c.g <= 0x00ff || c.g >= 0xff00)
969 && (c.b <= 0x00ff || c.b >= 0xff00))
970 bg_flags |= BG_TINT_BITAND;
971
972 if (has_shade
973 || c.r < 0xff00
974 || c.g < 0xff00
975 || c.b < 0xff00)
976 bg_flags |= BG_NEEDS_TINT; 727 bg_flags |= BG_NEEDS_TINT;
728 else
729 bg_flags &= ~BG_NEEDS_TINT;
977} 730}
978 731
979bool 732bool
980rxvt_term::bg_set_tint (rxvt_color &new_tint) 733rxvt_term::bg_set_tint (rxvt_color &new_tint)
981{ 734{
982 if (tint != new_tint) 735 if (!(bg_flags & BG_TINT_SET) || tint != new_tint)
983 { 736 {
984 tint = new_tint; 737 tint = new_tint;
738 bg_flags |= BG_TINT_SET;
739
740 rgba c;
741 tint.get (c);
742 if ((c.r <= 0x00ff || c.r >= 0xff00)
743 && (c.g <= 0x00ff || c.g >= 0xff00)
744 && (c.b <= 0x00ff || c.b >= 0xff00))
745 bg_flags |= BG_TINT_BITAND;
746 else
747 bg_flags &= ~BG_TINT_BITAND;
748
985 set_tint_shade_flags (); 749 set_tint_shade_flags ();
986 return true; 750 return true;
987 } 751 }
988 752
989 return false; 753 return false;
1030 params[i+2] = XDoubleToFixed (kernel[i] / sum); 794 params[i+2] = XDoubleToFixed (kernel[i] / sum);
1031} 795}
1032#endif 796#endif
1033 797
1034bool 798bool
1035rxvt_term::blur_pixmap (Pixmap pixmap, Visual *visual, int width, int height) 799rxvt_term::blur_pixmap (Pixmap pixmap, Visual *visual, int width, int height, int depth)
1036{ 800{
1037 bool ret = false; 801 bool ret = false;
1038#if XRENDER 802#if XRENDER
1039 if (!(bg_flags & BG_HAS_RENDER_CONV)) 803 if (!(bg_flags & BG_HAS_RENDER_CONV))
1040 return false; 804 return false;
1044 XFixed *params = (XFixed *)malloc ((size + 2) * sizeof (XFixed)); 808 XFixed *params = (XFixed *)malloc ((size + 2) * sizeof (XFixed));
1045 809
1046 XRenderPictureAttributes pa; 810 XRenderPictureAttributes pa;
1047 XRenderPictFormat *format = XRenderFindVisualFormat (dpy, visual); 811 XRenderPictFormat *format = XRenderFindVisualFormat (dpy, visual);
1048 812
813 pa.repeat = RepeatPad;
1049 Picture src = XRenderCreatePicture (dpy, pixmap, format, 0, &pa); 814 Picture src = XRenderCreatePicture (dpy, pixmap, format, CPRepeat, &pa);
815 Pixmap tmp = XCreatePixmap (dpy, pixmap, width, height, depth);
1050 Picture dst = XRenderCreatePicture (dpy, pixmap, format, 0, &pa); 816 Picture dst = XRenderCreatePicture (dpy, tmp, format, CPRepeat, &pa);
817 XFreePixmap (dpy, tmp);
1051 818
1052 if (kernel && params) 819 if (kernel && params)
1053 { 820 {
1054 if (h_blurRadius)
1055 {
1056 size = h_blurRadius * 2 + 1; 821 size = h_blurRadius * 2 + 1;
1057 get_gaussian_kernel (h_blurRadius, size, kernel, params); 822 get_gaussian_kernel (h_blurRadius, size, kernel, params);
1058 823
1059 XRenderSetPictureFilter (dpy, src, FilterConvolution, params, size+2); 824 XRenderSetPictureFilter (dpy, src, FilterConvolution, params, size+2);
1060 XRenderComposite (dpy, 825 XRenderComposite (dpy,
1061 PictOpSrc, 826 PictOpSrc,
1062 src, 827 src,
1063 None, 828 None,
1064 dst, 829 dst,
1065 0, 0, 830 0, 0,
1066 0, 0, 831 0, 0,
1067 0, 0, 832 0, 0,
1068 width, height); 833 width, height);
1069 }
1070 834
1071 if (v_blurRadius) 835 ::swap (src, dst);
1072 { 836
1073 size = v_blurRadius * 2 + 1; 837 size = v_blurRadius * 2 + 1;
1074 get_gaussian_kernel (v_blurRadius, size, kernel, params); 838 get_gaussian_kernel (v_blurRadius, size, kernel, params);
1075 ::swap (params[0], params[1]); 839 ::swap (params[0], params[1]);
1076 840
1077 XRenderSetPictureFilter (dpy, src, FilterConvolution, params, size+2); 841 XRenderSetPictureFilter (dpy, src, FilterConvolution, params, size+2);
1078 XRenderComposite (dpy, 842 XRenderComposite (dpy,
1079 PictOpSrc, 843 PictOpSrc,
1080 src, 844 src,
1081 None, 845 None,
1082 dst, 846 dst,
1083 0, 0, 847 0, 0,
1084 0, 0, 848 0, 0,
1085 0, 0, 849 0, 0,
1086 width, height); 850 width, height);
1087 }
1088 851
1089 ret = true; 852 ret = true;
1090 } 853 }
1091 854
1092 free (kernel); 855 free (kernel);
1100bool 863bool
1101rxvt_term::tint_pixmap (Pixmap pixmap, Visual *visual, int width, int height) 864rxvt_term::tint_pixmap (Pixmap pixmap, Visual *visual, int width, int height)
1102{ 865{
1103 bool ret = false; 866 bool ret = false;
1104 867
1105 if (bg_flags & BG_TINT_BITAND) 868 if (shade == 100 && (bg_flags & BG_TINT_BITAND))
1106 { 869 {
1107 XGCValues gcv; 870 XGCValues gcv;
1108 GC gc; 871 GC gc;
1109 872
1110 /* In this case we can tint image server-side getting significant 873 /* In this case we can tint image server-side getting significant
1122 } 885 }
1123 } 886 }
1124# if XRENDER 887# if XRENDER
1125 else if (bg_flags & BG_HAS_RENDER) 888 else if (bg_flags & BG_HAS_RENDER)
1126 { 889 {
1127 rgba c; 890 rgba c (rgba::MAX_CC, rgba::MAX_CC, rgba::MAX_CC);
1128 891
892 if (bg_flags & BG_TINT_SET)
1129 tint.get (c); 893 tint.get (c);
1130 894
1131 if (shade <= 100) 895 if (shade <= 100)
1132 { 896 {
1133 c.r = c.r * shade / 100; 897 c.r = c.r * shade / 100;
1134 c.g = c.g * shade / 100; 898 c.g = c.g * shade / 100;
1139 c.r = c.r * (200 - shade) / 100; 903 c.r = c.r * (200 - shade) / 100;
1140 c.g = c.g * (200 - shade) / 100; 904 c.g = c.g * (200 - shade) / 100;
1141 c.b = c.b * (200 - shade) / 100; 905 c.b = c.b * (200 - shade) / 100;
1142 } 906 }
1143 907
1144 XRenderPictFormat *solid_format = XRenderFindStandardFormat (dpy, PictStandardARGB32);
1145 XRenderPictFormat *format = XRenderFindVisualFormat (dpy, visual); 908 XRenderPictFormat *format = XRenderFindVisualFormat (dpy, visual);
1146 XRenderPictureAttributes pa;
1147 909
1148 Picture back_pic = XRenderCreatePicture (dpy, pixmap, format, 0, &pa); 910 Picture back_pic = XRenderCreatePicture (dpy, pixmap, format, 0, 0);
1149 911
1150 pa.repeat = True; 912 Picture overlay_pic = create_xrender_mask (dpy, pixmap, True, False);
1151 913
1152 Pixmap overlay_pmap = XCreatePixmap (dpy, pixmap, 1, 1, 32); 914 Picture mask_pic = create_xrender_mask (dpy, pixmap, True, True);
1153 Picture overlay_pic = XRenderCreatePicture (dpy, overlay_pmap, solid_format, CPRepeat, &pa);
1154 XFreePixmap (dpy, overlay_pmap);
1155
1156 pa.component_alpha = True;
1157 Pixmap mask_pmap = XCreatePixmap (dpy, pixmap, 1, 1, 32);
1158 Picture mask_pic = XRenderCreatePicture (dpy, mask_pmap, solid_format, CPRepeat | CPComponentAlpha, &pa);
1159 XFreePixmap (dpy, mask_pmap);
1160 915
1161 XRenderColor mask_c; 916 XRenderColor mask_c;
1162 917
1163 mask_c.alpha = 0xffff; 918 mask_c.alpha = 0xffff;
1164 mask_c.red = 919 mask_c.red =
1169 mask_c.alpha = 0; 924 mask_c.alpha = 0;
1170 mask_c.red = 0xffff - c.r; 925 mask_c.red = 0xffff - c.r;
1171 mask_c.green = 0xffff - c.g; 926 mask_c.green = 0xffff - c.g;
1172 mask_c.blue = 0xffff - c.b; 927 mask_c.blue = 0xffff - c.b;
1173 XRenderFillRectangle (dpy, PictOpSrc, mask_pic, &mask_c, 0, 0, 1, 1); 928 XRenderFillRectangle (dpy, PictOpSrc, mask_pic, &mask_c, 0, 0, 1, 1);
929
1174 XRenderComposite (dpy, PictOpOver, overlay_pic, mask_pic, back_pic, 0, 0, 0, 0, 0, 0, width, height); 930 XRenderComposite (dpy, PictOpOver, overlay_pic, mask_pic, back_pic, 0, 0, 0, 0, 0, 0, width, height);
1175 931
1176 if (shade > 100) 932 if (shade > 100)
1177 { 933 {
1178 mask_c.red = mask_c.green = mask_c.blue = 0xffff * (shade - 100) / 100;
1179 mask_c.alpha = 0; 934 mask_c.alpha = 0;
935 mask_c.red =
936 mask_c.green =
937 mask_c.blue = 0xffff * (shade - 100) / 100;
1180 XRenderFillRectangle (dpy, PictOpSrc, overlay_pic, &mask_c, 0, 0, 1, 1); 938 XRenderFillRectangle (dpy, PictOpSrc, overlay_pic, &mask_c, 0, 0, 1, 1);
1181 939
1182 XRenderComposite (dpy, PictOpOver, overlay_pic, None, back_pic, 0, 0, 0, 0, 0, 0, width, height); 940 XRenderComposite (dpy, PictOpOver, overlay_pic, None, back_pic, 0, 0, 0, 0, 0, 0, width, height);
1183 } 941 }
1184 942
1196/* 954/*
1197 * Builds a pixmap of the same size as the terminal window that contains 955 * Builds a pixmap of the same size as the terminal window that contains
1198 * the tiled portion of the root pixmap that is supposed to be covered by 956 * the tiled portion of the root pixmap that is supposed to be covered by
1199 * our window. 957 * our window.
1200 */ 958 */
1201unsigned long 959bool
1202rxvt_term::make_transparency_pixmap () 960rxvt_term::make_transparency_pixmap ()
1203{ 961{
1204 unsigned long result = 0; 962 bool ret = false;
1205 963
1206 /* root dimensions may change from call to call - but Display structure should 964 /* root dimensions may change from call to call - but Display structure should
1207 * be always up-to-date, so let's use it : 965 * be always up-to-date, so let's use it :
1208 */ 966 */
1209 int screen = display->screen; 967 int screen = display->screen;
1247#if XRENDER 1005#if XRENDER
1248 if (bg_flags & BG_HAS_RENDER) 1006 if (bg_flags & BG_HAS_RENDER)
1249 { 1007 {
1250 recoded_root_pmap = XCreatePixmap (dpy, vt, root_pmap_width, root_pmap_height, depth); 1008 recoded_root_pmap = XCreatePixmap (dpy, vt, root_pmap_width, root_pmap_height, depth);
1251 1009
1252 XRenderPictureAttributes pa;
1253
1254 XRenderPictFormat *src_format = XRenderFindVisualFormat (dpy, DefaultVisual (dpy, screen)); 1010 XRenderPictFormat *src_format = XRenderFindVisualFormat (dpy, DefaultVisual (dpy, screen));
1255 Picture src = XRenderCreatePicture (dpy, root_pixmap, src_format, 0, &pa); 1011 Picture src = XRenderCreatePicture (dpy, root_pixmap, src_format, 0, 0);
1256 1012
1257 XRenderPictFormat *dst_format = XRenderFindVisualFormat (dpy, visual); 1013 XRenderPictFormat *dst_format = XRenderFindVisualFormat (dpy, visual);
1258 Picture dst = XRenderCreatePicture (dpy, recoded_root_pmap, dst_format, 0, &pa); 1014 Picture dst = XRenderCreatePicture (dpy, recoded_root_pmap, dst_format, 0, 0);
1259 1015
1260 XRenderComposite (dpy, PictOpSrc, src, None, dst, 0, 0, 0, 0, 0, 0, root_pmap_width, root_pmap_height); 1016 XRenderComposite (dpy, PictOpSrc, src, None, dst, 0, 0, 0, 0, 0, 0, root_pmap_width, root_pmap_height);
1261 1017
1262 XRenderFreePicture (dpy, src); 1018 XRenderFreePicture (dpy, src);
1263 XRenderFreePicture (dpy, dst); 1019 XRenderFreePicture (dpy, dst);
1292 gc = XCreateGC (dpy, vt, GCFillStyle | GCTile | GCTileStipXOrigin | GCTileStipYOrigin, &gcv); 1048 gc = XCreateGC (dpy, vt, GCFillStyle | GCTile | GCTileStipXOrigin | GCTileStipYOrigin, &gcv);
1293 1049
1294 if (gc) 1050 if (gc)
1295 { 1051 {
1296 XFillRectangle (dpy, bg_pixmap, gc, 0, 0, window_width, window_height); 1052 XFillRectangle (dpy, bg_pixmap, gc, 0, 0, window_width, window_height);
1297 result |= BG_IS_VALID | (bg_flags & BG_EFFECTS_FLAGS); 1053 ret = true;
1298 XFreeGC (dpy, gc); 1054 unsigned long tr_flags = bg_flags & BG_EFFECTS_FLAGS;
1299 1055
1300 if (!(bg_flags & BG_CLIENT_RENDER)) 1056 if (!(bg_flags & BG_CLIENT_RENDER))
1301 { 1057 {
1302 if (bg_flags & BG_NEEDS_BLUR) 1058 if (bg_flags & BG_NEEDS_BLUR)
1303 { 1059 {
1304 if (blur_pixmap (bg_pixmap, visual, window_width, window_height)) 1060 if (blur_pixmap (bg_pixmap, visual, window_width, window_height, depth))
1305 result &= ~BG_NEEDS_BLUR; 1061 tr_flags &= ~BG_NEEDS_BLUR;
1306 } 1062 }
1307 if (bg_flags & BG_NEEDS_TINT) 1063 if (bg_flags & BG_NEEDS_TINT)
1308 { 1064 {
1309 if (tint_pixmap (bg_pixmap, visual, window_width, window_height)) 1065 if (tint_pixmap (bg_pixmap, visual, window_width, window_height))
1310 result &= ~BG_NEEDS_TINT; 1066 tr_flags &= ~BG_NEEDS_TINT;
1067 }
1068 if (tr_flags & BG_NEEDS_TINT)
1069 {
1070 XImage *ximage = XGetImage (dpy, bg_pixmap, 0, 0, bg_pmap_width, bg_pmap_height, AllPlanes, ZPixmap);
1071 if (ximage)
1072 {
1073 /* our own client-side tinting */
1074 tint_ximage (DefaultVisual (dpy, display->screen), ximage);
1075
1076 XPutImage (dpy, bg_pixmap, gc, ximage, 0, 0, 0, 0, ximage->width, ximage->height);
1077 XDestroyImage (ximage);
1078 }
1311 } 1079 }
1312 } /* server side rendering completed */ 1080 } /* server side rendering completed */
1081
1082 XFreeGC (dpy, gc);
1313 } 1083 }
1314 1084
1315 if (recoded_root_pmap != root_pixmap) 1085 if (recoded_root_pmap != root_pixmap)
1316 XFreePixmap (dpy, recoded_root_pmap); 1086 XFreePixmap (dpy, recoded_root_pmap);
1317 1087
1318 return result; 1088 return ret;
1319} 1089}
1320 1090
1321void 1091void
1322rxvt_term::bg_set_root_pixmap () 1092rxvt_term::bg_set_root_pixmap ()
1323{ 1093{
1330# endif /* ENABLE_TRANSPARENCY */ 1100# endif /* ENABLE_TRANSPARENCY */
1331 1101
1332bool 1102bool
1333rxvt_term::bg_render () 1103rxvt_term::bg_render ()
1334{ 1104{
1335 unsigned long tr_flags = 0; 1105 bool transparent = false;
1336 1106
1337 bg_invalidate (); 1107 bg_invalidate ();
1338# ifdef ENABLE_TRANSPARENCY 1108# ifdef ENABLE_TRANSPARENCY
1339 if (bg_flags & BG_IS_TRANSPARENT) 1109 if (bg_flags & BG_IS_TRANSPARENT)
1340 { 1110 {
1341 /* we need to re-generate transparency pixmap in that case ! */ 1111 /* we need to re-generate transparency pixmap in that case ! */
1342 tr_flags = make_transparency_pixmap (); 1112 transparent = make_transparency_pixmap ();
1343 if (tr_flags == 0) 1113 if (transparent)
1344 return false;
1345 bg_flags |= BG_IS_VALID; 1114 bg_flags |= BG_IS_VALID;
1346 } 1115 }
1347# endif 1116# endif
1348 1117
1349# ifdef BG_IMAGE_FROM_FILE 1118# ifdef BG_IMAGE_FROM_FILE
1350 if ((bg_flags & BG_IS_FROM_FILE) 1119 if (bg_flags & BG_IS_FROM_FILE)
1351 || (tr_flags & BG_EFFECTS_FLAGS))
1352 { 1120 {
1353 if (render_image (tr_flags)) 1121 if (render_image (transparent))
1354 bg_flags |= BG_IS_VALID; 1122 bg_flags |= BG_IS_VALID;
1355 }
1356# endif
1357
1358# if defined(ENABLE_TRANSPARENCY) && !defined(HAVE_AFTERIMAGE)
1359 XImage *result = NULL;
1360
1361 if (tr_flags & BG_NEEDS_TINT)
1362 {
1363 result = XGetImage (dpy, bg_pixmap, 0, 0, bg_pmap_width, bg_pmap_height, AllPlanes, ZPixmap);
1364 }
1365
1366 if (result)
1367 {
1368 /* our own client-side tinting */
1369 //if (tr_flags & BG_NEEDS_TINT)
1370 if (1)
1371 tint_ximage (DefaultVisual (dpy, display->screen), result);
1372
1373 GC gc = XCreateGC (dpy, vt, 0UL, NULL);
1374
1375 if (gc)
1376 {
1377 XPutImage (dpy, bg_pixmap, gc, result, 0, 0, 0, 0, result->width, result->height);
1378
1379 XFreeGC (dpy, gc);
1380 }
1381
1382 XDestroyImage (result);
1383 } 1123 }
1384# endif 1124# endif
1385 1125
1386 if (!(bg_flags & BG_IS_VALID)) 1126 if (!(bg_flags & BG_IS_VALID))
1387 { 1127 {
1402 1142
1403void 1143void
1404rxvt_term::bg_init () 1144rxvt_term::bg_init ()
1405{ 1145{
1406#ifdef ENABLE_TRANSPARENCY 1146#ifdef ENABLE_TRANSPARENCY
1407 rgba c (rgba::MAX_CC, rgba::MAX_CC, rgba::MAX_CC);
1408 tint.set (this, c);
1409 shade = 100; 1147 shade = 100;
1410#endif 1148#endif
1411 1149
1412 bg_flags &= ~(BG_HAS_RENDER | BG_HAS_RENDER_CONV); 1150 bg_flags &= ~(BG_HAS_RENDER | BG_HAS_RENDER_CONV);
1413#if XRENDER 1151#if XRENDER
1426#endif 1164#endif
1427} 1165}
1428 1166
1429#endif /* HAVE_BG_PIXMAP */ 1167#endif /* HAVE_BG_PIXMAP */
1430 1168
1431#if defined(ENABLE_TRANSPARENCY) && !defined(HAVE_AFTERIMAGE) 1169#ifdef ENABLE_TRANSPARENCY
1432/* based on code from aterm-0.4.2 */ 1170/* based on code from aterm-0.4.2 */
1433 1171
1434static inline void 1172static inline void
1435fill_lut (uint32_t *lookup, uint32_t mask, int sh, unsigned short low, unsigned short high) 1173fill_lut (uint32_t *lookup, uint32_t mask, int sh, unsigned short low, unsigned short high)
1436{ 1174{
1516 break; 1254 break;
1517 default: 1255 default:
1518 return; /* we do not support this color depth */ 1256 return; /* we do not support this color depth */
1519 } 1257 }
1520 1258
1521 rgba c; 1259 rgba c (rgba::MAX_CC, rgba::MAX_CC, rgba::MAX_CC);
1522 1260
1261 if (bg_flags & BG_TINT_SET)
1523 tint.get (c); 1262 tint.get (c);
1524 1263
1525 /* prepare limits for color transformation (each channel is handled separately) */ 1264 /* prepare limits for color transformation (each channel is handled separately) */
1526 if (shade > 100) 1265 if (shade > 100)
1527 { 1266 {
1528 c.r = c.r * (200 - shade) / 100; 1267 c.r = c.r * (200 - shade) / 100;
1548 /* apply table to input image (replacing colors by newly calculated ones) */ 1287 /* apply table to input image (replacing colors by newly calculated ones) */
1549 if (ximage->bits_per_pixel == 32 1288 if (ximage->bits_per_pixel == 32
1550 && (ximage->depth == 24 || ximage->depth == 32) 1289 && (ximage->depth == 24 || ximage->depth == 32)
1551 && ximage->byte_order == host_byte_order) 1290 && ximage->byte_order == host_byte_order)
1552 { 1291 {
1553 uint32_t *p1, *pf, *p, *pl; 1292 char *line = ximage->data;
1554 p1 = (uint32_t *) ximage->data;
1555 pf = (uint32_t *) (ximage->data + ximage->height * ximage->bytes_per_line);
1556 1293
1557 while (p1 < pf) 1294 for (int y = 0; y < ximage->height; y++)
1558 { 1295 {
1559 p = p1; 1296 uint32_t *p = (uint32_t *)line;
1560 pl = p1 + ximage->width; 1297 for (int x = 0; x < ximage->width; x++)
1561 for (; p < pl; p++)
1562 { 1298 {
1563 *p = lookup_r[(*p & 0xff0000) >> 16] | 1299 *p = lookup_r[(*p & 0xff0000) >> 16] |
1564 lookup_g[(*p & 0x00ff00) >> 8] | 1300 lookup_g[(*p & 0x00ff00) >> 8] |
1565 lookup_b[(*p & 0x0000ff)] | 1301 lookup_b[(*p & 0x0000ff)] |
1566 (*p & 0xff000000); 1302 (*p & 0xff000000);
1567 } 1303 p++;
1568 p1 = (uint32_t *) ((char *) p1 + ximage->bytes_per_line); 1304 }
1305 line += ximage->bytes_per_line;
1569 } 1306 }
1570 } 1307 }
1571 else 1308 else
1572 { 1309 {
1573 for (int y = 0; y < ximage->height; y++) 1310 for (int y = 0; y < ximage->height; y++)
1581 } 1318 }
1582 } 1319 }
1583 1320
1584 free (lookup); 1321 free (lookup);
1585} 1322}
1586#endif /* defined(ENABLE_TRANSPARENCY) && !defined(HAVE_AFTERIMAGE) */ 1323#endif /* ENABLE_TRANSPARENCY */

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines