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

Comparing rxvt-unicode/src/xpm.C (file contents):
Revision 1.61 by ayin, Tue Aug 7 15:23:11 2007 UTC vs.
Revision 1.62 by sasha, Tue Aug 7 22:43:33 2007 UTC

132 int smaller = MIN (image_size,window_size); 132 int smaller = MIN (image_size,window_size);
133 133
134 if (align >= 0 && align <= 50) 134 if (align >= 0 && align <= 50)
135 return diff * align / 100; 135 return diff * align / 100;
136 else if (align > 50 && align <= 100) 136 else if (align > 50 && align <= 100)
137 return window_size - image_size + diff * align / 100; 137 return window_size - image_size - diff * (100 - align) / 100;
138 else if (align > 100 && align <= 200 ) 138 else if (align > 100 && align <= 200 )
139 return ((align - 100) * smaller / 100) + window_size - smaller; 139 return ((align - 100) * smaller / 100) + window_size - smaller;
140 else if (align > -100 && align < 0) 140 else if (align > -100 && align < 0)
141 return ((align + 100) * smaller / 100) - image_size; 141 return ((align + 100) * smaller / 100) - image_size;
142 return 0; 142 return 0;
143} 143}
144 144
145static inline void 145static inline int
146make_clip_rectangle (int pos, int size, int target_size, int &clip_pos, int &clip_size) 146make_clip_rectangle (int pos, int size, int target_size, int &dst_pos, int &dst_size)
147{ 147{
148 if (size <= 0) 148 int src_pos = 0;
149 { /* special case - tiling */ 149 dst_pos = 0;
150 dst_size = size;
151 if (pos < 0 && size > target_size)
152 {
150 clip_pos = pos; 153 src_pos = -pos;
151 clip_size = target_size; 154 dst_size += pos;
152 } 155 }
153 else if (pos < 0) 156 else if (pos > 0)
154 {
155 clip_pos = 0;
156 clip_size = MIN (target_size, size + pos);
157 }
158 else
159 {
160 clip_pos = pos; 157 dst_pos = pos;
161 clip_size = size; 158
162 if (pos < target_size && (int)clip_size > target_size - pos) 159 if (dst_pos + dst_size > target_size)
163 clip_pos = target_size - pos; 160 dst_size = target_size - dst_pos;
164 } 161 return src_pos;
165} 162}
166 163
167bool 164bool
168bgPixmap_t::handle_geometry (const char *geom) 165bgPixmap_t::handle_geometry (const char *geom)
169{ 166{
267 w = h = bgPmap_defaultScale; 264 w = h = bgPmap_defaultScale;
268 } 265 }
269 else if (geom_flags & WidthValue) 266 else if (geom_flags & WidthValue)
270 { 267 {
271 if (!(geom_flags & HeightValue)) 268 if (!(geom_flags & HeightValue))
272 h = w; 269 h = w;
273 } 270 }
274 else 271 else
275 w = h; 272 w = h;
276 } 273 }
277 } /* done parsing geometry string */ 274 } /* done parsing geometry string */
278 else if (!(flags & bgPmap_geometrySet)) 275 else if (!(flags & bgPmap_geometrySet))
279 { /* default geometry - scaled and centered */ 276 { /* default geometry - scaled and centered */
280 x = y = bgPmap_defaultAlign; 277 x = y = bgPmap_defaultAlign;
281 w = h = bgPmap_defaultScale; 278 w = h = bgPmap_defaultScale;
282 } 279 }
283 280
284 if (!(flags & bgPmap_geometrySet)) 281 if (!(flags & bgPmap_geometrySet))
285 geom_flags |= WidthValue|HeightValue|XValue|YValue; 282 geom_flags |= WidthValue|HeightValue|XValue|YValue;
286 283
378 { 375 {
379 x = make_align_position (h_align, target_width, w > 0 ? w : (int)original_asim->width); 376 x = make_align_position (h_align, target_width, w > 0 ? w : (int)original_asim->width);
380 y = make_align_position (v_align, target_height, h > 0 ? h : (int)original_asim->height); 377 y = make_align_position (v_align, target_height, h > 0 ? h : (int)original_asim->height);
381 } 378 }
382 379
383 int dst_x, dst_y; 380 if (original_asim == NULL
384 int clip_width, clip_height; 381 || x >= target_width
385 382 || y >= target_height
386 make_clip_rectangle (x, w, target_width, dst_x, clip_width); 383 || (w > 0 && x + w <= 0)
387 make_clip_rectangle (y, h, target_height, dst_y, clip_height); 384 || (h > 0 && y + h <= 0))
388
389 /* TODO : actuall scaling code :) */
390 if (dst_x >= target_width || dst_y >= target_height
391 || clip_width <= 0 || clip_height <= 0 || original_asim == NULL)
392 { 385 {
393 result = background;
394 dst_x = dst_y = 0;
395 if (background) 386 if (background)
396 { 387 {
397 new_pmap_width = clip_width = background->width; 388 new_pmap_width = background->width;
398 new_pmap_height = clip_height = background->height; 389 new_pmap_height = background->height;
390 result = background;
391 if (background_tint != TINT_LEAVE_SAME)
392 {
393 ASImage* tmp = tile_asimage (target->asv, background, 0, 0,
394 target_width, target_height, background_tint,
395 ASA_XImage, 100, ASIMAGE_QUALITY_DEFAULT);
396 if (tmp)
397 result = tmp;
398 }
399 } 399 }
400 else 400 else
401 new_pmap_width = new_pmap_height = 0; 401 new_pmap_width = new_pmap_height = 0;
402 } 402 }
403 else 403 else
404 { 404 {
405 result = original_asim; 405 result = original_asim;
406 if ((w > 0 && w != original_asim->width) 406 if ((w > 0 && w != original_asim->width)
416 {/* if tiling - pixmap has to be sized exactly as the image */ 416 {/* if tiling - pixmap has to be sized exactly as the image */
417 if (h_scale == 0) 417 if (h_scale == 0)
418 new_pmap_width = result->width; 418 new_pmap_width = result->width;
419 if (v_scale == 0) 419 if (v_scale == 0)
420 new_pmap_height = result->height; 420 new_pmap_height = result->height;
421 /* we also need to tile our image in one or both directions */
422 if (h_scale == 0 || v_scale == 0)
423 {
424 ASImage *tmp = tile_asimage (target->asv, result,
425 (h_scale > 0) ? 0 : (int)result->width - x,
426 (v_scale > 0) ? 0 : (int)result->height - y,
427 result->width, result->height,
428 TINT_LEAVE_SAME, ASA_XImage,
429 100, ASIMAGE_QUALITY_DEFAULT);
430 if (tmp)
431 {
432 if (result != original_asim)
433 destroy_asimage (&result);
434 result = tmp;
435 }
436 }
421 } 437 }
422 else 438 else
423 {/* if blending background and image - pixmap has to be sized same as target window */ 439 {/* if blending background and image - pixmap has to be sized same as target window */
424 ASImageLayer *layers = create_image_layers (2); 440 ASImageLayer *layers = create_image_layers (2);
425 ASImage *merged_im = NULL; 441 ASImage *merged_im = NULL;
429 layers[0].clip_height = target_height; 445 layers[0].clip_height = target_height;
430 layers[0].tint = background_tint; 446 layers[0].tint = background_tint;
431 layers[1].im = result; 447 layers[1].im = result;
432 if (w <= 0) 448 if (w <= 0)
433 {/* tile horizontally */ 449 {/* tile horizontally */
434 layers[1].dst_x = dst_x - (int)result->width; 450 while (x > 0) x -= (int)result->width;
451 layers[1].dst_x = x;
435 layers[1].clip_width = result->width; 452 layers[1].clip_width = result->width+target_width;
436 } 453 }
437 else 454 else
438 {/* clip horizontally */ 455 {/* clip horizontally */
439 layers[1].dst_x = dst_x; 456 layers[1].dst_x = x;
440 layers[1].clip_width = clip_width; 457 layers[1].clip_width = result->width;
441 } 458 }
442 if (h <= 0) 459 if (h <= 0)
443 { 460 {
444 layers[1].dst_y = dst_y - (int)result->height; 461 while (y > 0) y -= (int)result->height;
462 layers[1].dst_y = y;
463 layers[1].clip_height = result->height + target_height;
464 }
465 else
466 {
467 layers[1].dst_y = y;
445 layers[1].clip_height = result->height; 468 layers[1].clip_height = result->height;
446 }
447 else
448 {
449 layers[1].dst_y = dst_y;
450 layers[1].clip_height = clip_height;
451 } 469 }
452 if (target->rs[Rs_blendtype]) 470 if (target->rs[Rs_blendtype])
453 { 471 {
454 layers[1].merge_scanlines = blend_scanlines_name2func (target->rs[Rs_blendtype]); 472 layers[1].merge_scanlines = blend_scanlines_name2func (target->rs[Rs_blendtype]);
455 if (layers[1].merge_scanlines == NULL) 473 if (layers[1].merge_scanlines == NULL)
460 if (tmp) 478 if (tmp)
461 { 479 {
462 if (result != original_asim) 480 if (result != original_asim)
463 destroy_asimage (&result); 481 destroy_asimage (&result);
464 result = tmp; 482 result = tmp;
465 dst_x = dst_y = 0;
466 clip_width = target_width;
467 clip_height = target_height;
468 } 483 }
469 free (layers); 484 free (layers);
470 } 485 }
471 } 486 }
472 487
497 } 512 }
498 /* fill with background color ( if result's not completely overlapping it)*/ 513 /* fill with background color ( if result's not completely overlapping it)*/
499 gcv.foreground = target->pix_colors[Color_bg]; 514 gcv.foreground = target->pix_colors[Color_bg];
500 gc = XCreateGC (target->dpy, target->vt, GCForeground, &gcv); 515 gc = XCreateGC (target->dpy, target->vt, GCForeground, &gcv);
501 516
517 int src_x = 0, src_y = 0, dst_x = 0, dst_y = 0;
518 int dst_width = result->width, dst_height = result->height;
519 if (background == NULL)
520 {
521 if (h_scale > 0)
522 src_x = make_clip_rectangle (x, result->width, new_pmap_width, dst_x, dst_width);
523 if (v_scale > 0)
524 src_y = make_clip_rectangle (y, result->height, new_pmap_height, dst_y, dst_height);
525
502 if (dst_x > 0 || dst_y > 0 526 if (dst_x > 0 || dst_y > 0
503 || dst_x + clip_width < new_pmap_width 527 || dst_x + dst_width < new_pmap_width
504 || dst_y + clip_height < new_pmap_height) 528 || dst_y + dst_height < new_pmap_height)
505 { 529 {
506 XFillRectangle (target->dpy, pixmap, gc, 0, 0, new_pmap_width, new_pmap_height); 530 XFillRectangle (target->dpy, pixmap, gc, 0, 0, new_pmap_width, new_pmap_height);
507 } 531 }
532 }
533
508 /* put result on pixmap */ 534 /* put result on pixmap */
535 if (dst_x < new_pmap_width && dst_y < new_pmap_height)
509 asimage2drawable (target->asv, pixmap, result, gc, 0, 0, dst_x, dst_y, clip_width, clip_height, True); 536 asimage2drawable (target->asv, pixmap, result, gc, src_x, src_y, dst_x, dst_y, dst_width, dst_height, True);
537
538 if (result != background && result != original_asim)
539 destroy_asimage (&result);
510 540
511 /* set target's background to pixmap */ 541 /* set target's background to pixmap */
512 XSetWindowBackgroundPixmap (target->dpy, target->vt, pixmap); 542 XSetWindowBackgroundPixmap (target->dpy, target->vt, pixmap);
513 543
514 XFreeGC (target->dpy, gc); 544 XFreeGC (target->dpy, gc);
524#endif 554#endif
525 555
526void 556void
527rxvt_term::resize_pixmap () 557rxvt_term::resize_pixmap ()
528{ 558{
529 XGCValues gcvalue; 559
530 GC gc;
531 unsigned int w = bgPixmap.h_scale*szHint.width/100;
532 unsigned int h = bgPixmap.v_scale*szHint.height/100;
533 int x = bgPixmap.h_align*szHint.width/100;
534 int y = bgPixmap.v_align*szHint.height/100;
535#ifdef HAVE_AFTERIMAGE
536 ASImage *im = bgPixmap.original_asim;
537#else
538 void *im = NULL;
539#endif
540/* preliminary cleanup - this needs to be integrated with check_our_parents() code */
541 if (bgPixmap.pixmap != None)
542 {
543 XFreePixmap (dpy, bgPixmap.pixmap);
544 bgPixmap.pixmap = None ;
545 }
546#ifdef ENABLE_TRANSPARENCY 560#ifdef ENABLE_TRANSPARENCY
547 if (option(Opt_transparent) && am_transparent) 561 if (option(Opt_transparent) && am_transparent)
548 { 562 {
549 /* we need to re-generate transparency pixmap in that case ! */ 563 /* we need to re-generate transparency pixmap in that case ! */
550 check_our_parents (); 564 check_our_parents ();
551 return; 565 return;
552 } 566 }
553#endif 567#endif
554
555 if (im == NULL)
556 { /* So be it: I'm not using pixmaps */
557 XSetWindowBackground (dpy, vt, pix_colors[Color_bg]);
558 return;
559 }
560
561 gcvalue.foreground = pix_colors[Color_bg];
562 gc = XCreateGC (dpy, vt, GCForeground, &gcvalue);
563
564 /* don't zoom pixmap too much nor expand really small pixmaps */
565 if (w > 16000)
566 w = 1;
567 if (h > 16000)
568 h = 1;
569
570#ifdef HAVE_AFTERIMAGE 568#ifdef HAVE_AFTERIMAGE
571 if (w == 0) 569 bgPixmap.render_asim(this, NULL, TINT_LEAVE_SAME);
572 w = im->width;
573 if (h == 0)
574 h = im->height;
575
576 if (w != im->width || h != im->height)
577 {
578 ASImage *tmp = scale_asimage (asv, im, w, h, (x == 0 && y == 0)?ASA_XImage:ASA_ASImage, 0, ASIMAGE_QUALITY_DEFAULT);
579 if (tmp != NULL)
580 im = tmp;
581 }
582 bgPixmap.pmap_width = MIN(w,szHint.width);
583 bgPixmap.pmap_height = MIN(h,szHint.height);
584#if 0 /* TODO: fix that! */
585 if (x != 0 || y != 0)
586 {
587 ASImage *tmp = tile_asimage (asv, im, x, y, w, h, TINT_LEAVE_SAME, ASA_XImage, 0, ASIMAGE_QUALITY_DEFAULT);
588 if (tmp != NULL)
589 {
590 if (im != bgPixmap.original_asim)
591 destroy_asimage (&im);
592 im = tmp;
593 }
594 }
595#endif
596 bgPixmap.pixmap = XCreatePixmap (dpy, vt, bgPixmap.pmap_width, bgPixmap.pmap_height, depth);
597 bgPixmap.pmap_depth = depth;
598
599 asimage2drawable (asv, bgPixmap.pixmap, im, gc, 0, 0, 0, 0, bgPixmap.pmap_width, bgPixmap.pmap_height, True);
600
601 if (im != bgPixmap.original_asim)
602 destroy_asimage (&im);
603#endif 570#endif
604 if( bgPixmap.pixmap )
605 XSetWindowBackgroundPixmap (dpy, vt, bgPixmap.pixmap);
606
607 XFreeGC (dpy, gc);
608} 571}
609 572
610void 573void
611rxvt_term::set_bgPixmap (const char *file) 574rxvt_term::set_bgPixmap (const char *file)
612{ 575{
637 bgPixmap.original_asim = get_asimage( asimman, f, 0xFFFFFFFF, 100 ); 600 bgPixmap.original_asim = get_asimage( asimman, f, 0xFFFFFFFF, 100 );
638 free( f ); 601 free( f );
639 } 602 }
640#endif 603#endif
641 } 604 }
642 605 resize_pixmap (); /* TODO: temporary fix - should be done by the caller! */
643 resize_pixmap ();
644} 606}
645 607
646#endif /* XPM_BACKGROUND */ 608#endif /* XPM_BACKGROUND */
647#endif /* HAVE_BG_PIXMAP */ 609#endif /* HAVE_BG_PIXMAP */
648 610
1075 { 1037 {
1076 destroy_asimage (&back_im); 1038 destroy_asimage (&back_im);
1077 back_im = tmp; 1039 back_im = tmp;
1078 } 1040 }
1079 } 1041 }
1080 1042 /* TODO: temporary fix - redo the logic, so that same function can do both
1081 if (bgPixmap.original_asim != NULL) 1043 transparency and non-transparency */
1082 { 1044 bgPixmap.render_asim (this, back_im, tint);
1083 ASImageLayer *layers = create_image_layers (2);
1084 ASImage *merged_im = NULL;
1085 int fore_w, fore_h;
1086
1087 layers[0].im = back_im;
1088 layers[0].clip_width = szHint.width;
1089 layers[0].clip_height = szHint.height;
1090 layers[0].tint = tint;
1091 layers[1].im = bgPixmap.original_asim;
1092
1093 fore_w = (bgPixmap.h_scale == 0) ? bgPixmap.original_asim->width : bgPixmap.h_scale*szHint.width/100;
1094 fore_h = (bgPixmap.v_scale == 0) ? bgPixmap.original_asim->height : bgPixmap.v_scale*szHint.height/100;
1095
1096 if (fore_w != bgPixmap.original_asim->width
1097 || fore_h != bgPixmap.original_asim->height)
1098 {
1099 layers[1].im = scale_asimage (asv,
1100 bgPixmap.original_asim,
1101 fore_w, fore_h,
1102 ASA_ASImage, 100,
1103 ASIMAGE_QUALITY_DEFAULT);
1104 }
1105 layers[1].clip_width = szHint.width;
1106 layers[1].clip_height = szHint.height;
1107
1108 if (rs[Rs_blendtype])
1109 {
1110 layers[1].merge_scanlines = blend_scanlines_name2func (rs[Rs_blendtype]);
1111 if (layers[1].merge_scanlines == NULL)
1112 layers[1].merge_scanlines = alphablend_scanlines;
1113 }
1114 PRINT_BACKGROUND_OP_TIME;
1115 merged_im = merge_layers (asv, layers, 2, szHint.width, szHint.height,
1116 ASA_XImage, 0, ASIMAGE_QUALITY_DEFAULT);
1117 if (layers[1].im != bgPixmap.original_asim)
1118 destroy_asimage (&(layers[1].im));
1119 free (layers);
1120
1121 if (merged_im != NULL)
1122 {
1123 destroy_asimage (&back_im);
1124 back_im = merged_im;
1125 }
1126 PRINT_BACKGROUND_OP_TIME;
1127 }
1128 else if (tint != TINT_LEAVE_SAME)
1129 {
1130 ASImage* tmp = tile_asimage (asv, back_im, 0, 0, szHint.width, szHint.height, tint, ASA_XImage, 100, ASIMAGE_QUALITY_DEFAULT);
1131 if (tmp)
1132 {
1133 destroy_asimage (&back_im);
1134 back_im = tmp;
1135 }
1136 PRINT_BACKGROUND_OP_TIME;
1137 }
1138 asimage2drawable (asv, bgPixmap.pixmap, back_im, gc, 0, 0, 0, 0, szHint.width, szHint.height, True);
1139 destroy_asimage (&back_im); 1045 destroy_asimage (&back_im);
1046
1140 } /* back_im != NULL */ 1047 } /* back_im != NULL */
1141 else 1048 else
1142 success = False; 1049 success = False;
1143 } 1050 }
1144#else /* HAVE_AFTERIMAGE */ 1051#else /* HAVE_AFTERIMAGE */

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines