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

Comparing rxvt-unicode/src/rxvttoolkit.C (file contents):
Revision 1.38 by root, Mon Jan 30 19:46:13 2006 UTC vs.
Revision 1.40 by root, Tue Jan 31 16:19:16 2006 UTC

560refcache<rxvt_display> displays; 560refcache<rxvt_display> displays;
561 561
562///////////////////////////////////////////////////////////////////////////// 562/////////////////////////////////////////////////////////////////////////////
563 563
564bool 564bool
565rxvt_color::alloc (rxvt_screen *screen, rxvt_rgba rgba) 565rxvt_color::alloc (rxvt_screen *screen, const rxvt_rgba &color)
566{ 566{
567#if XFT 567#if XFT
568 XRenderPictFormat *format; 568 XRenderPictFormat *format;
569 569
570 // FUCKING Xft gets it wrong, of course, so work around it 570 // FUCKING Xft gets it wrong, of course, so work around it
572 // XRenderQueryPictIndexValues themselves plenty. 572 // XRenderQueryPictIndexValues themselves plenty.
573 if ((screen->visual->c_class == TrueColor || screen->visual->c_class == DirectColor) 573 if ((screen->visual->c_class == TrueColor || screen->visual->c_class == DirectColor)
574 && (format = XRenderFindVisualFormat (screen->xdisp, screen->visual))) 574 && (format = XRenderFindVisualFormat (screen->xdisp, screen->visual)))
575 { 575 {
576 // the fun lies in doing everything manually... 576 // the fun lies in doing everything manually...
577 c.color.red = rgba.r; 577 c.color.red = color.r;
578 c.color.green = rgba.g; 578 c.color.green = color.g;
579 c.color.blue = rgba.b; 579 c.color.blue = color.b;
580 c.color.alpha = rgba.a; 580 c.color.alpha = color.a;
581 581
582 c.pixel = ((rgba.r * format->direct.redMask / rxvt_rgba::MAX_CC) << format->direct.red ) 582 c.pixel = ((color.r * format->direct.redMask / rxvt_rgba::MAX_CC) << format->direct.red )
583 | ((rgba.g * format->direct.greenMask / rxvt_rgba::MAX_CC) << format->direct.green) 583 | ((color.g * format->direct.greenMask / rxvt_rgba::MAX_CC) << format->direct.green)
584 | ((rgba.b * format->direct.blueMask / rxvt_rgba::MAX_CC) << format->direct.blue ) 584 | ((color.b * format->direct.blueMask / rxvt_rgba::MAX_CC) << format->direct.blue )
585 | ((rgba.a * format->direct.alphaMask / rxvt_rgba::MAX_CC) << format->direct.alpha); 585 | ((color.a * format->direct.alphaMask / rxvt_rgba::MAX_CC) << format->direct.alpha);
586 586
587 return true; 587 return true;
588 } 588 }
589 else 589 else
590 { 590 {
591 XRenderColor d; 591 XRenderColor d;
592 592
593 d.red = rgba.r; 593 d.red = color.r;
594 d.green = rgba.g; 594 d.green = color.g;
595 d.blue = rgba.b; 595 d.blue = color.b;
596 d.alpha = rgba.a; 596 d.alpha = color.a;
597 597
598 return XftColorAllocValue (screen->xdisp, screen->visual, screen->cmap, &d, &c); 598 return XftColorAllocValue (screen->xdisp, screen->visual, screen->cmap, &d, &c);
599 } 599 }
600#else 600#else
601 if (screen->visual->c_class == TrueColor || screen->visual->c_class == DirectColor) 601 if (screen->visual->c_class == TrueColor || screen->visual->c_class == DirectColor)
602 { 602 {
603 p = (rgba.r * (screen->visual->red_mask >> ctz (screen->visual->red_mask )) 603 p = (color.r * (screen->visual->red_mask >> ctz (screen->visual->red_mask ))
604 / rxvt_rgba::MAX_CC) << ctz (screen->visual->red_mask ) 604 / rxvt_rgba::MAX_CC) << ctz (screen->visual->red_mask )
605 | (rgba.g * (screen->visual->green_mask >> ctz (screen->visual->green_mask)) 605 | (color.g * (screen->visual->green_mask >> ctz (screen->visual->green_mask))
606 / rxvt_rgba::MAX_CC) << ctz (screen->visual->green_mask) 606 / rxvt_rgba::MAX_CC) << ctz (screen->visual->green_mask)
607 | (rgba.b * (screen->visual->blue_mask >> ctz (screen->visual->blue_mask )) 607 | (color.b * (screen->visual->blue_mask >> ctz (screen->visual->blue_mask ))
608 / rxvt_rgba::MAX_CC) << ctz (screen->visual->blue_mask ); 608 / rxvt_rgba::MAX_CC) << ctz (screen->visual->blue_mask );
609 609
610 return true; 610 return true;
611 } 611 }
612 else 612 else
613 { 613 {
614 XColor xc; 614 XColor xc;
615 615
616 xc.red = rgba.r; 616 xc.red = color.r;
617 xc.green = rgba.g; 617 xc.green = color.g;
618 xc.blue = rgba.b; 618 xc.blue = color.b;
619 619
620 if (XAllocColor (screen->xdisp, screen->cmap, &xc)) 620 if (XAllocColor (screen->xdisp, screen->cmap, &xc))
621 { 621 {
622 p = xc.pixel; 622 p = xc.pixel;
623 return true; 623 return true;
624 } 624 }
625 else 625 else
626 p = (rgba.r + rgba.g + rgba.b) > 128*3 626 p = (color.r + color.g + color.b) > 128*3
627 ? WhitePixelOfScreen (DefaultScreenOfDisplay (screen->xdisp)) 627 ? WhitePixelOfScreen (DefaultScreenOfDisplay (screen->xdisp))
628 : BlackPixelOfScreen (DefaultScreenOfDisplay (screen->xdisp)); 628 : BlackPixelOfScreen (DefaultScreenOfDisplay (screen->xdisp));
629 } 629 }
630#endif 630#endif
631 631
633} 633}
634 634
635bool 635bool
636rxvt_color::set (rxvt_screen *screen, const char *name) 636rxvt_color::set (rxvt_screen *screen, const char *name)
637{ 637{
638 int l = strlen (name);
639 rxvt_rgba r; 638 rxvt_rgba c;
640 char eos; 639 char eos;
641 int mult; 640 int skip;
642 XColor xc, xc_exact;
643 641
644 // parse a number of non-standard ARGB colour specifications 642 if (1 <= sscanf (name, "[%hx]%n", &c.a, &skip))
645 if ( l == 1+4*1 && 4 == sscanf (name, "#%1hx%1hx%1hx%1hx%c", &r.a, &r.r, &r.g, &r.b, &eos))
646 mult = rxvt_rgba::MAX_CC / 0x0010;
647 else if (l == 1+4*2 && 4 == sscanf (name, "#%2hx%2hx%2hx%2hx%c", &r.a, &r.r, &r.g, &r.b, &eos))
648 mult = rxvt_rgba::MAX_CC / 0x0100;
649 else if (l == 1+4*4 && 4 == sscanf (name, "#%4hx%4hx%4hx%4hx%c", &r.a, &r.r, &r.g, &r.b, &eos))
650 mult = rxvt_rgba::MAX_CC / 0x0100;
651 else if (l == 4+5*4 && 4 == sscanf (name, "rgba:%hx/%hx/%hx/%hx%c", &r.r, &r.g, &r.b, &r.a, &eos))
652 mult = rxvt_rgba::MAX_CC / 0xffff;
653 else if (XParseColor (screen->xdisp, screen->cmap, name, &xc))
654 { 643 {
655 r.r = xc.red; 644 switch (skip)
656 r.g = xc.green; 645 {
657 r.b = xc.blue; 646 case 2 + 1: c.a *= rxvt_rgba::MAX_CC / 0x000f; break;
658 mult = rxvt_rgba::MAX_CC / 0xffff; 647 case 2 + 2: c.a *= rxvt_rgba::MAX_CC / 0x00ff; break;
648 case 2 + 3: c.a *= rxvt_rgba::MAX_CC / 0x0fff; break;
649 case 2 + 4: c.a *= rxvt_rgba::MAX_CC / 0xffff; break;
650 }
651
652 name += skip;
659 } 653 }
660 else 654 else
655 c.a = rxvt_rgba::MAX_CC;
656
657 // parse the non-standard rgba format
658 if (strlen (name) != 4+5*4 || 4 != sscanf (name, "rgba:%hx/%hx/%hx/%hx%c", &c.r, &c.g, &c.b, &c.a, &eos))
661 { 659 {
660 XColor xc, xc_exact;
661
662 if (XParseColor (screen->xdisp, screen->cmap, name, &xc))
663 {
664 c.r = xc.red;
665 c.g = xc.green;
666 c.b = xc.blue;
667 }
668 else
669 {
670 c.r = 0xffff;
671 c.g = 0x6969;
672 c.b = 0xb4b4;
673
662 rxvt_warn ("failed to allocate color '%s', using pink instead.\n", name); 674 rxvt_warn ("unable to parse color '%s', using pink instead.\n", name);
663 r.r = 255; 675 }
664 r.g = 105;
665 r.b = 180;
666 mult = rxvt_rgba::MAX_CC / 0x00ff;
667 } 676 }
668 677
669 r.r *= mult; r.g *= mult; r.b *= mult; r.a *= mult;
670
671 return set (screen, r); 678 return set (screen, c);
672} 679}
673 680
674bool 681bool
675rxvt_color::set (rxvt_screen *screen, rxvt_rgba rgba) 682rxvt_color::set (rxvt_screen *screen, const rxvt_rgba &color)
676{ 683{
677 bool got = alloc (screen, rgba); 684 bool got = alloc (screen, color);
678 685
679#if !ENABLE_MINIMAL 686#if !ENABLE_MINIMAL
680 int cmap_size = screen->visual->map_entries; 687 int cmap_size = screen->visual->map_entries;
681 688
682 if (!got 689 if (!got
693 int diff = 0x7fffffffUL; 700 int diff = 0x7fffffffUL;
694 XColor *best = colors; 701 XColor *best = colors;
695 702
696 for (int i = 0; i < cmap_size; i++) 703 for (int i = 0; i < cmap_size; i++)
697 { 704 {
698 int d = (squared_diff<int> (rgba.r >> 2, colors [i].red >> 2)) 705 int d = (squared_diff<int> (color.r >> 2, colors [i].red >> 2))
699 + (squared_diff<int> (rgba.g >> 2, colors [i].green >> 2)) 706 + (squared_diff<int> (color.g >> 2, colors [i].green >> 2))
700 + (squared_diff<int> (rgba.b >> 2, colors [i].blue >> 2)); 707 + (squared_diff<int> (color.b >> 2, colors [i].blue >> 2));
701 708
702 if (d < diff) 709 if (d < diff)
703 { 710 {
704 diff = d; 711 diff = d;
705 best = colors + i; 712 best = colors + i;
706 } 713 }
707 } 714 }
708 715
709 //rxvt_warn ("could not allocate %04x %04x %04x, getting %04x %04x %04x instead (%d)\n", 716 //rxvt_warn ("could not allocate %04x %04x %04x, getting %04x %04x %04x instead (%d)\n",
710 // rgba.r, rgba.g, rgba.b, best->red, best->green, best->blue, diff); 717 // color.r, color.g, color.b, best->red, best->green, best->blue, diff);
711 718
712 got = alloc (screen, rxvt_rgba (best->red, best->green, best->blue)); 719 got = alloc (screen, rxvt_rgba (best->red, best->green, best->blue));
713 720
714 delete colors; 721 delete colors;
715 } 722 }
716#endif 723#endif
717 724
718 return got; 725 return got;
719} 726}
720 727
721void 728void
722rxvt_color::get (rxvt_screen *screen, rxvt_rgba &rgba) 729rxvt_color::get (rxvt_screen *screen, rxvt_rgba &color)
723{ 730{
724#if XFT 731#if XFT
725 rgba.r = c.color.red; 732 color.r = c.color.red;
726 rgba.g = c.color.green; 733 color.g = c.color.green;
727 rgba.b = c.color.blue; 734 color.b = c.color.blue;
728 rgba.a = c.color.alpha; 735 color.a = c.color.alpha;
729#else 736#else
730 XColor c; 737 XColor c;
731 738
732 c.pixel = p; 739 c.pixel = p;
733 XQueryColor (screen->xdisp, screen->cmap, &c); 740 XQueryColor (screen->xdisp, screen->cmap, &c);
734 741
735 rgba.r = c.red; 742 color.r = c.red;
736 rgba.g = c.green; 743 color.g = c.green;
737 rgba.b = c.blue; 744 color.b = c.blue;
738 rgba.a = rxvt_rgba::MAX_CC; 745 color.a = rxvt_rgba::MAX_CC;
739#endif 746#endif
740} 747}
741 748
742void 749void
743rxvt_color::free (rxvt_screen *screen) 750rxvt_color::free (rxvt_screen *screen)
748 XFreeColors (screen->xdisp, screen->cmap, &p, 1, AllPlanes); 755 XFreeColors (screen->xdisp, screen->cmap, &p, 1, AllPlanes);
749#endif 756#endif
750} 757}
751 758
752rxvt_color 759rxvt_color
753rxvt_color::fade (rxvt_screen *screen, int percent) 760rxvt_color::fade (rxvt_screen *screen, int percent, const rxvt_rgba &to)
754{ 761{
755 rxvt_color faded;
756
757 rxvt_rgba c; 762 rxvt_rgba c;
758 get (screen, c); 763 get (screen, c);
759 764
760 c.r = lerp (0, c.r, percent);
761 c.g = lerp (0, c.g, percent);
762 c.b = lerp (0, c.b, percent);
763
764 faded.set (screen, c);
765
766 return faded;
767}
768
769rxvt_color
770rxvt_color::fade (rxvt_screen *screen, int percent, rxvt_color &fadeto)
771{
772 rxvt_rgba c, fc;
773 rxvt_color faded; 765 rxvt_color faded;
774
775 get (screen, c);
776 fadeto.get (screen, fc);
777
778 faded.set ( 766 faded.set (
779 screen, 767 screen,
780 rxvt_rgba ( 768 rxvt_rgba (
781 lerp (fc.r, c.r, percent), 769 lerp (to.r, c.r, percent),
782 lerp (fc.g, c.g, percent), 770 lerp (to.g, c.g, percent),
783 lerp (fc.b, c.b, percent), 771 lerp (to.b, c.b, percent),
784 lerp (fc.a, c.a, percent) 772 lerp (to.a, c.a, percent)
785 ) 773 )
786 ); 774 );
787 775
788 return faded; 776 return faded;
789} 777}

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines