| line | stmt | bran | cond | sub | pod | time | code | 
| 1 |  |  |  |  |  |  | #  You may distribute under the terms of either the GNU General Public License | 
| 2 |  |  |  |  |  |  | #  or the Artistic License (the same terms as Perl itself) | 
| 3 |  |  |  |  |  |  | # | 
| 4 |  |  |  |  |  |  | #  (C) Paul Evans, 2009-2021 -- leonerd@leonerd.org.uk | 
| 5 |  |  |  |  |  |  |  | 
| 6 |  |  |  |  |  |  | package Convert::Color::XTerm 0.06; | 
| 7 |  |  |  |  |  |  |  | 
| 8 | 2 |  |  | 2 |  | 1325 | use v5.14; | 
|  | 2 |  |  |  |  | 14 |  | 
| 9 | 2 |  |  | 2 |  | 11 | use warnings; | 
|  | 2 |  |  |  |  | 4 |  | 
|  | 2 |  |  |  |  | 58 |  | 
| 10 | 2 |  |  | 2 |  | 11 | use base qw( Convert::Color::RGB8 ); | 
|  | 2 |  |  |  |  | 3 |  | 
|  | 2 |  |  |  |  | 1097 |  | 
| 11 |  |  |  |  |  |  |  | 
| 12 |  |  |  |  |  |  | __PACKAGE__->register_color_space( 'xterm' ); | 
| 13 |  |  |  |  |  |  |  | 
| 14 | 2 |  |  | 2 |  | 51402 | use Carp; | 
|  | 2 |  |  |  |  | 6 |  | 
|  | 2 |  |  |  |  | 1882 |  | 
| 15 |  |  |  |  |  |  |  | 
| 16 |  |  |  |  |  |  | =head1 NAME | 
| 17 |  |  |  |  |  |  |  | 
| 18 |  |  |  |  |  |  | C - indexed colors used by XTerm | 
| 19 |  |  |  |  |  |  |  | 
| 20 |  |  |  |  |  |  | =head1 SYNOPSIS | 
| 21 |  |  |  |  |  |  |  | 
| 22 |  |  |  |  |  |  | Directly: | 
| 23 |  |  |  |  |  |  |  | 
| 24 |  |  |  |  |  |  | use Convert::Color::XTerm; | 
| 25 |  |  |  |  |  |  |  | 
| 26 |  |  |  |  |  |  | my $red = Convert::Color::XTerm->new( 1 ); | 
| 27 |  |  |  |  |  |  |  | 
| 28 |  |  |  |  |  |  | Via L: | 
| 29 |  |  |  |  |  |  |  | 
| 30 |  |  |  |  |  |  | use Convert::Color; | 
| 31 |  |  |  |  |  |  |  | 
| 32 |  |  |  |  |  |  | my $cyan = Convert::Color->new( 'xterm:14' ); | 
| 33 |  |  |  |  |  |  |  | 
| 34 |  |  |  |  |  |  | =head1 DESCRIPTION | 
| 35 |  |  |  |  |  |  |  | 
| 36 |  |  |  |  |  |  | This subclass of L provides lookup of the colors that | 
| 37 |  |  |  |  |  |  | F uses by default. Note that the module is not intelligent enough to | 
| 38 |  |  |  |  |  |  | actually parse the XTerm configuration on a machine, nor to query a running | 
| 39 |  |  |  |  |  |  | terminal for its actual colors. It simply implements the colors that are | 
| 40 |  |  |  |  |  |  | present as defaults in the XTerm source code. | 
| 41 |  |  |  |  |  |  |  | 
| 42 |  |  |  |  |  |  | It implements the complete 256-color model in XTerm. This range consists of: | 
| 43 |  |  |  |  |  |  |  | 
| 44 |  |  |  |  |  |  | =over 4 | 
| 45 |  |  |  |  |  |  |  | 
| 46 |  |  |  |  |  |  | =item * | 
| 47 |  |  |  |  |  |  |  | 
| 48 |  |  |  |  |  |  | 0-7: The basic VGA colors, dark intensity. 7 is a "dark" white, i.e. a light | 
| 49 |  |  |  |  |  |  | grey. | 
| 50 |  |  |  |  |  |  |  | 
| 51 |  |  |  |  |  |  | =item * | 
| 52 |  |  |  |  |  |  |  | 
| 53 |  |  |  |  |  |  | 8-15: The basic VGA colors, light intensity. 8 represents a "light" black, | 
| 54 |  |  |  |  |  |  | i.e. a dark grey. | 
| 55 |  |  |  |  |  |  |  | 
| 56 |  |  |  |  |  |  | =item * | 
| 57 |  |  |  |  |  |  |  | 
| 58 |  |  |  |  |  |  | 16-231: A 6x6x6 RGB color cube. | 
| 59 |  |  |  |  |  |  |  | 
| 60 |  |  |  |  |  |  | I This can also be specified as C where | 
| 61 |  |  |  |  |  |  | each of R, G and B can be C<0> to C<5>, or C<0%> to C<100%>. | 
| 62 |  |  |  |  |  |  |  | 
| 63 |  |  |  |  |  |  | =item * | 
| 64 |  |  |  |  |  |  |  | 
| 65 |  |  |  |  |  |  | 232-255: 24 greyscale ramp. | 
| 66 |  |  |  |  |  |  |  | 
| 67 |  |  |  |  |  |  | I This can also be specified as C, where | 
| 68 |  |  |  |  |  |  | GREY is C<0> to C<23>, or C<0%> to C<100%>. | 
| 69 |  |  |  |  |  |  |  | 
| 70 |  |  |  |  |  |  | =back | 
| 71 |  |  |  |  |  |  |  | 
| 72 |  |  |  |  |  |  | =cut | 
| 73 |  |  |  |  |  |  |  | 
| 74 |  |  |  |  |  |  | my @color; | 
| 75 |  |  |  |  |  |  |  | 
| 76 |  |  |  |  |  |  | sub _init_colors | 
| 77 |  |  |  |  |  |  | { | 
| 78 |  |  |  |  |  |  | # The first 16 colors are dark and light versions of the basic 8 VGA colors. | 
| 79 |  |  |  |  |  |  | # XTerm itself pulls these from the X11 database, except for light blue. | 
| 80 |  |  |  |  |  |  | # These color names from xterm's charproc.c | 
| 81 |  |  |  |  |  |  |  | 
| 82 | 1 |  |  | 1 |  | 2 | my @colnames; | 
| 83 |  |  |  |  |  |  |  | 
| 84 | 1 | 50 |  |  |  | 3 | if( eval { require Convert::Color::X11; Convert::Color::X11->colors } ) { | 
|  | 1 |  |  |  |  | 523 |  | 
|  | 1 |  |  |  |  | 881 |  | 
| 85 | 0 |  |  |  |  | 0 | @colnames = (qw( | 
| 86 |  |  |  |  |  |  | x11:black   x11:red3     x11:green3 x11:yellow3 | 
| 87 |  |  |  |  |  |  | x11:blue2   x11:magenta3 x11:cyan3  x11:gray90 | 
| 88 |  |  |  |  |  |  | x11:gray50  x11:red      x11:green  x11:yellow | 
| 89 |  |  |  |  |  |  | rgb8:5C5CFF x11:magenta  x11:cyan   x11:white | 
| 90 |  |  |  |  |  |  | )); | 
| 91 |  |  |  |  |  |  | } | 
| 92 |  |  |  |  |  |  | else { | 
| 93 | 1 |  |  |  |  | 143 | @colnames = (qw( | 
| 94 |  |  |  |  |  |  | rgb8:000000 rgb8:cd0000 rgb8:00cd00 rgb8:cdcd00 | 
| 95 |  |  |  |  |  |  | rgb8:0000ee rgb8:cd00cd rgb8:00cdcd rgb8:e5e5e5 | 
| 96 |  |  |  |  |  |  | rgb8:7f7f7f rgb8:ff0000 rgb8:00ff00 rgb8:ffff00 | 
| 97 |  |  |  |  |  |  | rgb8:5c5cff rgb8:ff00ff rgb8:00ffff rgb8:ffffff | 
| 98 |  |  |  |  |  |  | )); | 
| 99 |  |  |  |  |  |  | } | 
| 100 |  |  |  |  |  |  |  | 
| 101 | 1 |  |  |  |  | 5 | foreach my $index ( 0 .. $#colnames ) | 
| 102 |  |  |  |  |  |  | { | 
| 103 | 16 |  |  |  |  | 159 | my $c_tmp = Convert::Color->new( $colnames[$index] ); | 
| 104 | 16 |  |  |  |  | 10940 | $color[$index] = __PACKAGE__->SUPER::new( $c_tmp->as_rgb8->rgb8 ); | 
| 105 | 16 |  |  |  |  | 696 | $color[$index]->[3] = $index; | 
| 106 |  |  |  |  |  |  | } | 
| 107 |  |  |  |  |  |  |  | 
| 108 |  |  |  |  |  |  | # These descriptions and formulae from xterm's 256colres.pl | 
| 109 |  |  |  |  |  |  |  | 
| 110 |  |  |  |  |  |  | # Next is a 6x6x6 color cube, with an attempt at a gamma correction | 
| 111 | 1 |  |  |  |  | 12 | foreach my $red ( 0 .. 5 ) { | 
| 112 | 6 |  |  |  |  | 12 | foreach my $green ( 0 .. 5 ) { | 
| 113 | 36 |  |  |  |  | 58 | foreach my $blue ( 0 .. 5 ) { | 
| 114 | 216 |  |  |  |  | 348 | my $index = 16 + ($red*36) + ($green*6) + $blue; | 
| 115 |  |  |  |  |  |  |  | 
| 116 |  |  |  |  |  |  | $color[$index] = __PACKAGE__->SUPER::new( | 
| 117 | 216 | 100 |  |  |  | 328 | map { $_ ? $_*40 + 55 : 0 } ( $red, $green, $blue ) | 
|  | 648 |  |  |  |  | 1267 |  | 
| 118 |  |  |  |  |  |  | ); | 
| 119 | 216 |  |  |  |  | 4222 | $color[$index]->[3] = $index; | 
| 120 |  |  |  |  |  |  | } | 
| 121 |  |  |  |  |  |  | } | 
| 122 |  |  |  |  |  |  | } | 
| 123 |  |  |  |  |  |  |  | 
| 124 |  |  |  |  |  |  | # Finally a 24-level greyscale ramp | 
| 125 | 1 |  |  |  |  | 4 | foreach my $grey ( 0 .. 23 ) { | 
| 126 | 24 |  |  |  |  | 35 | my $index = 232 + $grey; | 
| 127 | 24 |  |  |  |  | 84 | my $whiteness = $grey*10 + 8; | 
| 128 |  |  |  |  |  |  |  | 
| 129 | 24 |  |  |  |  | 55 | $color[$index] = __PACKAGE__->SUPER::new( $whiteness, $whiteness, $whiteness ); | 
| 130 | 24 |  |  |  |  | 461 | $color[$index]->[3] = $index; | 
| 131 |  |  |  |  |  |  | } | 
| 132 |  |  |  |  |  |  | } | 
| 133 |  |  |  |  |  |  |  | 
| 134 |  |  |  |  |  |  | __PACKAGE__->register_palette( | 
| 135 |  |  |  |  |  |  | enumerate_once => sub { | 
| 136 |  |  |  |  |  |  | @color or _init_colors; | 
| 137 |  |  |  |  |  |  | @color | 
| 138 |  |  |  |  |  |  | }, | 
| 139 |  |  |  |  |  |  | ); | 
| 140 |  |  |  |  |  |  |  | 
| 141 |  |  |  |  |  |  | =head1 CONSTRUCTOR | 
| 142 |  |  |  |  |  |  |  | 
| 143 |  |  |  |  |  |  | =cut | 
| 144 |  |  |  |  |  |  |  | 
| 145 |  |  |  |  |  |  | =head2 new | 
| 146 |  |  |  |  |  |  |  | 
| 147 |  |  |  |  |  |  | $color = Convert::Color::XTerm->new( $index ) | 
| 148 |  |  |  |  |  |  |  | 
| 149 |  |  |  |  |  |  | Returns a new object to represent the color at that index. | 
| 150 |  |  |  |  |  |  |  | 
| 151 |  |  |  |  |  |  | =cut | 
| 152 |  |  |  |  |  |  |  | 
| 153 |  |  |  |  |  |  | sub _index_or_percent | 
| 154 |  |  |  |  |  |  | { | 
| 155 | 8 |  |  | 8 |  | 37 | my ( $name, $val, $max ) = @_; | 
| 156 |  |  |  |  |  |  |  | 
| 157 | 8 | 100 |  |  |  | 36 | if( $val =~ m/^(\d+)%$/ ) { | 
|  |  | 50 |  |  |  |  |  | 
| 158 | 4 | 50 |  |  |  | 19 | $1 <= 100 or croak "Convert::Color::XTerm: Invalid percentage for $name: '$val'"; | 
| 159 | 4 |  |  |  |  | 15 | return int( $max * $1 / 100 ); | 
| 160 |  |  |  |  |  |  | } | 
| 161 |  |  |  |  |  |  | elsif( $val =~ m/^(\d+)$/ ) { | 
| 162 | 4 | 50 |  |  |  | 14 | $1 <= $max or croak "Convert::Color::XTerm: Invalid index for $name: '$val'"; | 
| 163 | 4 |  |  |  |  | 12 | return $1; | 
| 164 |  |  |  |  |  |  | } | 
| 165 |  |  |  |  |  |  | else { | 
| 166 | 0 |  |  |  |  | 0 | croak "Convert::Color::XTerm: Invalid value for $name: '$val'"; | 
| 167 |  |  |  |  |  |  | } | 
| 168 |  |  |  |  |  |  | } | 
| 169 |  |  |  |  |  |  |  | 
| 170 |  |  |  |  |  |  | sub new | 
| 171 |  |  |  |  |  |  | { | 
| 172 | 6 |  |  | 6 | 1 | 621 | my $class = shift; | 
| 173 | 6 | 50 |  |  |  | 26 | @_ == 1 or | 
| 174 |  |  |  |  |  |  | croak "usage: Convert::Color::XTerm->new( INDEX )"; | 
| 175 |  |  |  |  |  |  |  | 
| 176 | 6 | 100 |  |  |  | 20 | @color or _init_colors; | 
| 177 |  |  |  |  |  |  |  | 
| 178 | 6 | 100 |  |  |  | 54 | if( $_[0] =~ m/^grey\((.*)\)$/ ) { | 
|  |  | 100 |  |  |  |  |  | 
|  |  | 50 |  |  |  |  |  | 
| 179 | 2 |  |  |  |  | 8 | my $grey = _index_or_percent( grey => $1, 23 ); | 
| 180 | 2 |  |  |  |  | 10 | return $color[232 + $grey]; | 
| 181 |  |  |  |  |  |  | } | 
| 182 |  |  |  |  |  |  | elsif( $_[0] =~ m/^rgb\((.*),(.*),(.*)\)$/ ) { | 
| 183 | 2 |  |  |  |  | 7 | my $red   = _index_or_percent( red   => $1, 5 ); | 
| 184 | 2 |  |  |  |  | 7 | my $green = _index_or_percent( green => $2, 5 ); | 
| 185 | 2 |  |  |  |  | 6 | my $blue  = _index_or_percent( blue  => $3, 5 ); | 
| 186 | 2 |  |  |  |  | 11 | return $color[16 + 36*$red + 6*$green + $blue]; | 
| 187 |  |  |  |  |  |  | } | 
| 188 |  |  |  |  |  |  | elsif( $_[0] =~ m/^(\d+)$/ ) { | 
| 189 | 2 |  |  |  |  | 8 | my $index = $1; | 
| 190 |  |  |  |  |  |  |  | 
| 191 | 2 | 50 | 33 |  |  | 30 | $index >= 0 and $index < 256 or | 
| 192 |  |  |  |  |  |  | croak "No such XTerm color at index '$index'"; | 
| 193 |  |  |  |  |  |  |  | 
| 194 | 2 |  |  |  |  | 17 | return $color[$index]; | 
| 195 |  |  |  |  |  |  | } | 
| 196 |  |  |  |  |  |  | else { | 
| 197 | 0 |  |  |  |  | 0 | croak "Convert::Color::XTerm: Expected index, grey() or rgb() specification, got '$_[0]'"; | 
| 198 |  |  |  |  |  |  | } | 
| 199 |  |  |  |  |  |  | } | 
| 200 |  |  |  |  |  |  |  | 
| 201 |  |  |  |  |  |  | =head1 METHODS | 
| 202 |  |  |  |  |  |  |  | 
| 203 |  |  |  |  |  |  | =cut | 
| 204 |  |  |  |  |  |  |  | 
| 205 |  |  |  |  |  |  | =head2 index | 
| 206 |  |  |  |  |  |  |  | 
| 207 |  |  |  |  |  |  | $index = $color->index | 
| 208 |  |  |  |  |  |  |  | 
| 209 |  |  |  |  |  |  | The index of the XTerm color. | 
| 210 |  |  |  |  |  |  |  | 
| 211 |  |  |  |  |  |  | =cut | 
| 212 |  |  |  |  |  |  |  | 
| 213 |  |  |  |  |  |  | sub index | 
| 214 |  |  |  |  |  |  | { | 
| 215 | 7 |  |  | 7 | 1 | 24912 | my $self = shift; | 
| 216 | 7 |  |  |  |  | 34 | return $self->[3]; | 
| 217 |  |  |  |  |  |  | } | 
| 218 |  |  |  |  |  |  |  | 
| 219 |  |  |  |  |  |  | =head1 SEE ALSO | 
| 220 |  |  |  |  |  |  |  | 
| 221 |  |  |  |  |  |  | =over 4 | 
| 222 |  |  |  |  |  |  |  | 
| 223 |  |  |  |  |  |  | =item * | 
| 224 |  |  |  |  |  |  |  | 
| 225 |  |  |  |  |  |  | L - color space conversions | 
| 226 |  |  |  |  |  |  |  | 
| 227 |  |  |  |  |  |  | =back | 
| 228 |  |  |  |  |  |  |  | 
| 229 |  |  |  |  |  |  | =head1 AUTHOR | 
| 230 |  |  |  |  |  |  |  | 
| 231 |  |  |  |  |  |  | Paul Evans | 
| 232 |  |  |  |  |  |  |  | 
| 233 |  |  |  |  |  |  | =cut | 
| 234 |  |  |  |  |  |  |  | 
| 235 |  |  |  |  |  |  | 0x55AA; |